从Java到C++——从union到VARIANT与CComVariant的深层剖析
我第一次用VARIANT和CComVariant的时候完全不明白它是怎么回事,为它什么数据类型都可以存放,什么数据都可以被可以初始化?里面到底是怎么实现的?感觉又神奇又迷惑!我们在上一节中讲了union的用法之后你也许想到了大概是怎么回事了。没错,union可以帮我们实现这一个神奇的功能。而且VARIANT定义中确实使用了union。如果你还不明白,那我们就自己来模拟实现一个类似于CComVariant功能的类把,废话不多说,看代码:
CVariate.h:
#ifndef CVARIATE_H #define CVARIATE_H #include <string.h> //====================================================== 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_HCVariate.cpp:
#include "../include/CVariate.h" #include <iostream> 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; }Test.cpp:
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_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 ** 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; };
http://blog.csdn.net/nppg2008/article/details/7885139
http://blog.csdn.net/china_chentao/article/details/4059698
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。