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

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

      我第一次用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_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; };

相关说明
參考文章:

你可能感兴趣的文章
【OC梳理】description
查看>>
一篇不太一样的RxJava介绍(二):关于操作符背后的故事
查看>>
FFmpeg模块介绍
查看>>
张家口a货翡翠,梧州a货翡翠
查看>>
JS Object的静态方法汇总( 上 )
查看>>
到手机里面去点击信任就行了。每次都是这样出错。
查看>>
java B2B2C Springcloud多租户电子商城系统-Eureka服务端与客户端常用配置
查看>>
(十一)java版b2b2c社交电商spring cloud分布式微服务-docker部署spring cloud项目
查看>>
jvm疯狂吞占内存,罪魁祸首是谁?
查看>>
表格存储Tablestore权威指南(持续更新)
查看>>
java B2B2C源码电子商城系统-Kafka快速入门
查看>>
Spring Cloud云服务 - HongHu架构common-service 项目构建过程
查看>>
hadoop中hive原理及安装
查看>>
pear默认安装后一个小bug
查看>>
我的友情链接
查看>>
nginx-通过Nginx统计当前每个域名流量
查看>>
家庭电路 功率和负荷
查看>>
SECURITY-Dockerfile写法
查看>>
openGL坐标系
查看>>
vim
查看>>