博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从Java到C++——从union到VARIANT与CComVariant的深层剖析
阅读量:6709 次
发布时间:2019-06-25

本文共 11422 字,大约阅读时间需要 38 分钟。

hot3.png

      我第一次用VARIANTCComVariant的时候完全不明白它是怎么回事,为它什么数据类型都可以存放,什么数据都可以被可以初始化?里面到底是怎么实现的?感觉又神奇又迷惑!我们在上一节中讲了union的用法之后你也许想到了大概是怎么回事了。没错,union可以帮我们实现这一个神奇的功能。而且VARIANT定义中确实使用了union。如果你还不明白,那我们就自己来模拟实现一个类似于CComVariant功能的类把,废话不多说,看代码:

CVariate.h:

#ifndef CVARIATE_H#define CVARIATE_H#include 
//======================================================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
CVariate.cpp:
#include "../include/CVariate.h"#include 
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_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_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 ** 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_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_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 ** 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_UINTstruct __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_UINTstruct __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_UINTstruct __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_UINTstruct __tagBRECORD {PVOID pvRecord;IRecordInfo * pRecInfo;} __VARIANT_NAME_4; --- VT_RECORD} __VARIANT_NAME_3;} __VARIANT_NAME_2;DECIMAL decVal;} __VARIANT_NAME_1;};

相关说明
参考文章:

转载于:https://my.oschina.net/verynix/blog/365803

你可能感兴趣的文章
一个小需求引发的思考
查看>>
慎用System.nanoTime()
查看>>
算法的时间复杂度
查看>>
基础设施即代码:Terraform和AWS无服务器
查看>>
反模式的经典 - Mockito设计解析
查看>>
Visual Studio 15.7预览版4改进Git、C++支持
查看>>
微软宣布支持基于虚拟机的Azure IOT Edge服务
查看>>
来自社区的Visual Studio Code使用体验和教程
查看>>
[deviceone开发]-cnodejs论坛移动端App
查看>>
智能指针shared_ptr(effective modern c++笔记)
查看>>
NSDate格式化小例
查看>>
spring 基础
查看>>
java中finally和return的执行顺序
查看>>
MySQL分区表(优化)
查看>>
XP与XP互连
查看>>
linux驱动杂谈2
查看>>
使用linux内核,打造自己的linux
查看>>
Nginx--安装和配置
查看>>
Spark 的 Shell操作,核心概念,构建独立应用
查看>>
可能吞噬硬件的无服务器云
查看>>