我第一次用VARIANT和CComVariant的时候全然不明确它是怎么回事,为它什么数据类型都能够存放。什么数据都能够被能够初始化?里面究竟是怎么实现的?感觉又奇妙又迷惑!我们在上一节中讲了union的使用方法之后你或许想到了大概是怎么回事了。没错。union能够帮我们实现这一个奇妙的功能。并且VARIANT定义中确实使用了union。假设你还不明确,那我们就自己来模拟实现一个相似于CComVariant功能的类把,废话不多说,看代码:
CVariate.h:
#ifndef CVARIATE_H#define CVARIATE_H#includeCVariate.cpp://======================================================const unsigned int DEFAULT_STRLEN = 256;//=======================================================//自定义一个类用于存放随意类型的数据,以模拟类型VARIANT的功能。class CVariate{public: CVariate() : type(INT), nVal(0){} //默认构造函数。初始化nVal,值为0 virtual ~CVariate(){}; //虚构函数,不做不论什么处理 CVariate(const CVariate& val) : type(val.type) //拷贝构造函数 { CopyUnion(val); } CVariate &operator=(char c) { type = CHAR; cVal = c; return *this; } CVariate &operator=(short int sn) { type = SHORT; snVal = sn; return *this; } CVariate &operator=(int i) { type = INT; nVal = i; return *this; } CVariate &operator=(long l) { type = LONG; lVal = l; return *this; } CVariate &operator=(float f) { type = FLOAT; fVal = f; return *this; } CVariate &operator=(double d) { type = DOUBLE; dVal = d; return *this; } CVariate &operator=(const char* str); void CopyUnion(const CVariate& val); //数据的拷贝 void DisplayValue();private: enum {CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, STR}type; //为不同的数据类型定义一个枚举值 union //union,能够存入各种类型的数据 { char cVal; short snVal; int nVal; long lVal; float fVal; double dVal; char strVal[DEFAULT_STRLEN]; };};#endif // CVARIATE_H
#include "../include/CVariate.h"#includeTest.cpp:CVariate& CVariate::operator=(const char* str){ if(strlen(str) >= DEFAULT_STRLEN) { std::cerr << "The length of string is out of memory." << std::endl; } else { strcpy(strVal, str); type = STR; } return *this;}void CVariate::CopyUnion(const CVariate& val){ switch(val.type) { case CVariate::CHAR: cVal = val.cVal; break; case CVariate::SHORT: snVal = val.snVal; break; case CVariate::INT: nVal = val.nVal; break; case CVariate::LONG: lVal = val.lVal; break; case CVariate::FLOAT: fVal = val.fVal; break; case CVariate::DOUBLE: dVal = val.dVal; break; case CVariate::STR: if(strlen(val.strVal) >= DEFAULT_STRLEN) { std::cerr << "The length of string is out of memory." << std::endl; break; } else { strcpy(strVal, val.strVal); } break; default: return; }}void CVariate::DisplayValue(){ switch(type) { case CVariate::CHAR: std::cout << cVal; break; case CVariate::SHORT: std::cout << snVal; break; case CVariate::INT: std::cout << nVal; break; case CVariate::LONG: std::cout << lVal; break; case CVariate::FLOAT: std::cout << fVal; break; case CVariate::DOUBLE: std::cout << dVal; break; case CVariate::STR: char s[255]; strcpy(s, strVal); std::cout << s; break; default: return; } std::cout << std::endl;}
int main(){ CVariate cVal; cVal.DisplayValue(); cVal = 125; cVal.DisplayValue(); CVariate cVal2(cVal); cVal2.DisplayValue(); cVal2 = 188.598; cVal2.DisplayValue(); cVal2 = "Hello World."; cVal2.DisplayValue(); return 0;}结果例如以下:
VARIANT的结构能够參考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义例如以下:
struct tagVARIANT {union {struct __tagVARIANT {VARTYPE vt;WORD wReserved1;WORD wReserved2;WORD wReserved3;union {ULONGLONG ullVal; ---VT_UI8LONGLONG llVal; ---VT_I8LONG lVal; ---VT_I4 */BYTE bVal; ---VT_UI1 */SHORT iVal; ---VT_I2 */FLOAT fltVal; ---VT_R4 */DOUBLE dblVal; ---VT_R8 */VARIANT_BOOL boolVal; ---VT_BOOL */_VARIANT_BOOL bool; ---(obsolete) */SCODE scode; ---VT_ERROR */CY cyVal; ---VT_CY */DATE date; ---VT_DATE */BSTR bstrVal; ---VT_BSTR */IUnknown * punkVal; ---VT_UNKNOWN */IDispatch * pdispVal; ---VT_DISPATCH */SAFEARRAY * parray; ---VT_ARRAY */BYTE * pbVal; ---VT_BYREF|VT_UI1 */SHORT * piVal; ---VT_BYREF|VT_I2 */LONG * plVal; ---VT_BYREF|VT_I4 */LONGLONG * pllVal; ---VT_BYREF|VT_I8 */FLOAT * pfltVal; ---VT_BYREF|VT_R4 */DOUBLE * pdblVal; ---VT_BYREF|VT_R8 */VARIANT_BOOL *pboolVal; ---VT_BYREF|VT_BOOL */_VARIANT_BOOL *pbool; ---(obsolete) */SCODE * pscode; ---VT_BYREF|VT_ERROR */CY * pcyVal; ---VT_BYREF|VT_CY */DATE * pdate; ---VT_BYREF|VT_DATE */BSTR * pbstrVal; ---VT_BYREF|VT_BSTR */IUnknown ** ppunkValVARIANT的结构能够參考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。
struct tagVARIANT { union { struct __tagVARIANT { VARTYPE vt; WORD wReserved1; WORD wReserved2; WORD wReserved3; union { ULONGLONG ullVal; ---VT_UI8 LONGLONG llVal; ---VT_I8 LONG lVal; ---VT_I4 */ BYTE bVal; ---VT_UI1 */ SHORT iVal; ---VT_I2 */ FLOAT fltVal; ---VT_R4 */ DOUBLE dblVal; ---VT_R8 */ VARIANT_BOOL boolVal; ---VT_BOOL */ _VARIANT_BOOL bool; ---(obsolete) */ SCODE scode; ---VT_ERROR */ CY cyVal; ---VT_CY */ DATE date; ---VT_DATE */ BSTR bstrVal; ---VT_BSTR */ IUnknown * punkVal; ---VT_UNKNOWN */ IDispatch * pdispVal; ---VT_DISPATCH */ SAFEARRAY * parray; ---VT_ARRAY */ BYTE * pbVal; ---VT_BYREF|VT_UI1 */ SHORT * piVal; ---VT_BYREF|VT_I2 */ LONG * plVal; ---VT_BYREF|VT_I4 */ LONGLONG * pllVal; ---VT_BYREF|VT_I8 */ FLOAT * pfltVal; ---VT_BYREF|VT_R4 */ DOUBLE * pdblVal; ---VT_BYREF|VT_R8 */ VARIANT_BOOL *pboolVal; ---VT_BYREF|VT_BOOL */ _VARIANT_BOOL *pbool; ---(obsolete) */ SCODE * pscode; ---VT_BYREF|VT_ERROR */ CY * pcyVal; ---VT_BYREF|VT_CY */ DATE * pdate; ---VT_BYREF|VT_DATE */ BSTR * pbstrVal; ---VT_BYREF|VT_BSTR */ IUnknown ** ppunkVal; ---VT_BYREF|VT_UNKNOWN */ IDispatch ** ppdispVal; ---VT_BYREF|VT_DISPATCH */ SAFEARRAY ** pparray; ---VT_BYREF|VT_ARRAY */ VARIANT * pvarVal; ---VT_BYREF|VT_VARIANT */ PVOID byref; ---Generic ByRef */ CHAR cVal; ---VT_I1 */ USHORT uiVal; ---VT_UI2 */ ULONG ulVal; ---VT_UI4 */ INT intVal; ---VT_INT */ VARIANT的结构能够參考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。 struct tagVARIANT { union { struct __tagVARIANT { VARTYPE vt; WORD wReserved1; WORD wReserved2; WORD wReserved3; union { ULONGLONG ullVal; ---VT_UI8 LONGLONG llVal; ---VT_I8 LONG lVal; ---VT_I4 */ BYTE bVal; ---VT_UI1 */ SHORT iVal; ---VT_I2 */ FLOAT fltVal; ---VT_R4 */ DOUBLE dblVal; ---VT_R8 */ VARIANT_BOOL boolVal; ---VT_BOOL */ _VARIANT_BOOL bool; ---(obsolete) */ SCODE scode; ---VT_ERROR */ CY cyVal; ---VT_CY */ DATE date; ---VT_DATE */ BSTR bstrVal; ---VT_BSTR */ IUnknown * punkVal; ---VT_UNKNOWN */ IDispatch * pdispVal; ---VT_DISPATCH */ SAFEARRAY * parray; ---VT_ARRAY */ BYTE * pbVal; ---VT_BYREF|VT_UI1 */ SHORT * piVal; ---VT_BYREF|VT_I2 */ LONG * plVal; ---VT_BYREF|VT_I4 */ LONGLONG * pllVal; ---VT_BYREF|VT_I8 */ FLOAT * pfltVal; ---VT_BYREF|VT_R4 */ DOUBLE * pdblVal; ---VT_BYREF|VT_R8 */ VARIANT_BOOL *pboolVal; ---VT_BYREF|VT_BOOL */ _VARIANT_BOOL *pbool; ---(obsolete) */ SCODE * pscode; ---VT_BYREF|VT_ERROR */ CY * pcyVal; ---VT_BYREF|VT_CY */ DATE * pdate; ---VT_BYREF|VT_DATE */ BSTR * pbstrVal; ---VT_VARIANT的结构能够參考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。
struct tagVARIANT { union { struct __tagVARIANT { VARTYPE vt; WORD wReserved1; WORD wReserved2; WORD wReserved3; union { ULONGLONG ullVal; ---VT_UI8 LONGLONG llVal; ---VT_I8 LONG lVal; ---VT_I4 */ BYTE bVal; ---VT_UI1 */ SHORT iVal; ---VT_I2 */ FLOAT fltVal; ---VT_R4 */ DOUBLE dblVal; ---VT_R8 */ VARIANT_BOOL boolVal; ---VT_BOOL */ _VARIANT_BOOL bool; ---(obsolete) */ SCODE scode; ---VT_ERROR */ CY cyVal; ---VT_CY */ DATE date; ---VT_DATE */ BSTR bstrVal; ---VT_BSTR */ IUnknown * punkVal; ---VT_UNKNOWN */ IDispatch * pdispVal; ---VT_DISPATCH */ SAFEARRAY * parray; ---VT_ARRAY */ BYTE * pbVal; ---VT_BYREF|VT_UI1 */ SHORT * piVal; ---VT_BYREF|VT_I2 */ LONG * plVal; ---VT_BYREF|VT_I4 */ LONGLONG * pllVal; ---VT_BYREF|VT_I8 */ FLOAT * pfltVal; ---VT_BYREF|VT_R4 */ DOUBLE * pdblVal; ---VT_BYREF|VT_R8 */ VARIANT_BOOL *pboolVal; ---VT_BYREF|VT_BOOL */ _VARIANT_BOOL *pbool; ---(obsolete) */ SCODE * pscode; ---VT_BYREF|VT_ERROR */ CY * pcyVal; ---VT_BYREF|VT_CY */ DATE * pdate; ---VT_BYREF|VT_DATE */ BSTR * pbstrVal; ---VT_BYREF|VT_BSTR */ IUnknown ** ppunkVal; ---VT_BYREF|VT_UNKNOWN */ IDispatch ** ppdispVal; ---VT_BYREF|VT_DISPATCH */ SAFEARRAY ** pparray; ---VT_BYREF|VT_ARRAY */ VARIANT * pvarVal; ---VT_BYREF|VT_VARIANT */ PVOID byref; ---Generic ByRef */ CHAR cVal; ---VT_I1 */ USHORT uiVal; ---VT_UI2 */ ULONG ulVal; ---VT_UI4 */ INT intVal; ---VT_INT */ UINT uintVal; ---VT_UINT */ DECIMAL * pdecVal; ---VT_BYREF|VT_DECIMAL */ CHAR * pcVal; ---VT_BYREF|VT_I1 */ USHORT * puiVal; ---VT_BYREF|VT_UI2 */ ULONG * pulVal; ---VT_BYREF|VT_UI4 */ ULONGLONG * pullVal; --- VT_BYREF|VT_UI8 */ INT * pintVal; ---VT_BYREF|VT_INT */ UINT * puintVal; ---VT_BYREF|VT_UINT struct __tagBRECORD { PVOID pvRecord; IRecordInfo * pRecInfo; } __VARIANT_NAME_4; --- VT_RECORD } __VARIANT_NAME_3; } __VARIANT_NAME_2; DECIMAL decVal; } __VARIANT_NAME_1; };BYREF|VT_BSTR */ IUnknown ** ppunkVal; ---VT_BYREF|VT_UNKNOWN */ IDispatch ** ppdispVal; ---VT_BYREF|VT_DISPATCH */ SAFEARRAY ** pparray; ---VT_BYREF|VT_ARRAY */ VARIANT * pvarVal; ---VT_BYREF|VT_VARIANT */ PVOID byref; ---Generic ByRef */ CHAR cVal; ---VT_I1 */ USHORT uiVal; ---VT_UI2 */ ULONG ulVal; ---VT_UI4 */ INT intVal; ---VT_INT */ UINT uintVal; ---VT_UINT */ DECIMAL * pdecVal; ---VT_BYREF|VT_DECIMAL */ CHAR * pcVal; ---VT_BYREF|VT_I1 */ USHORT * puiVal; ---VT_BYREF|VT_UI2 */ ULONG * pulVal; ---VT_BYREF|VT_UI4 */ ULONGLONG * pullVal; --- VT_BYREF|VT_UI8 */ INT * pintVal; ---VT_BYREF|VT_INT */ UINT * puintVal; ---VT_BYREF|VT_UINT struct __tagBRECORD { PVOID pvRecord; IRecordInfo * pRecInfo; } __VARIANT_NAME_4; --- VT_RECORD } __VARIANT_NAME_3; } __VARIANT_NAME_2; DECIMAL decVal; } __VARIANT_NAME_1; }; UINT uintVal; ---VT_UINT */ DECIMAL * pdecVal; ---VT_BYREF|VT_DECIMAL */ CHAR * pcVal; ---VT_BYREF|VT_I1 */ USHORT * puiVal; ---VT_BYREF|VT_UI2 */ ULONG * pulVal; ---VT_BYREF|VT_UI4 */ ULONGLONG * pullVal; --- VT_BYREF|VT_UI8 */ INT * pintVal; ---VT_BYREF|VT_INT */ UINT * puintVal; ---VT_BYREF|VT_UINT struct __tagBRECORD { PVOID pvRecord; IRecordInfo * pRecInfo; } __VARIANT_NAME_4; --- VT_RECORD } __VARIANT_NAME_3; } __VARIANT_NAME_2; DECIMAL decVal; } __VARIANT_NAME_1; };; ---VT_BYREF|VT_UNKNOWN */ IDispatch ** ppdispVal; ---VT_BYREF|VT_DISPATCH */ SAFEARRAY ** pparray; ---VT_BYREF|VT_ARRAY */ VARIANT * pvarVal; ---VT_BYREF|VT_VARIANT */ PVOID byref; ---Generic ByRef */ CHAR cVal; ---VT_I1 */ USHORT uiVal; ---VT_UI2 */ ULONG ulVal; ---VT_UI4 */ INT intVal; ---VT_INT */ UINT uintVal; ---VT_UINT */ DECIMAL * pdecVal; ---VT_BYREF|VT_DECIMAL */ CHAR * pcVal; ---VT_BYREF|VT_I1 */ USHORT * puiVal; ---VT_BYREF|VT_UI2 */ ULONG * pulVal; ---VT_BYREF|VT_UI4 */ ULONGLONG * pullVal; --- VT_BYREF|VT_UI8 */ INT * pintVal; ---VT_BYREF|VT_INT */ UINT * puintVal; ---VT_BYREF|VT_UINT struct __tagBRECORD { PVOID pvRecord; IRecordInfo * pRecInfo; } __VARIANT_NAME_4; --- VT_RECORD } __VARIANT_NAME_3; } __VARIANT_NAME_2; DECIMAL decVal; } __VARIANT_NAME_1; };
相关说明 參考文章: