从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_H
CVariate.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;
};
相关说明參考文章:
从Java到C++——从union到VARIANT与CComVariant的深层剖析的更多相关文章
- Java锁-Synchronized深层剖析
Java锁-Synchronized深层剖析 前言 Java锁的问题,可以说是每个JavaCoder绕不开的一道坎.如果只是粗浅地了解Synchronized等锁的简单应用,那么就没什么谈的了,也不建 ...
- Java 并查集Union Find
对于一组数据,主要支持两种动作: union isConnected public interface UF { int getSize(); boolean isConnected(int p,in ...
- Java 中Iterator 、Vector、ArrayList、List 使用深入剖析
标签:Iterator Java List ArrayList Vector 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构.这些 ...
- 关于CString与VARIANT(CComVariant)之间的转化
一.VARIANT.CComVariant类与CString是什么: CString是MFC定义的字符串类,VARIANT是COM标准为了使COM组件能够被各种语言使用(vc++.vb.java.py ...
- Variant OLE automation
The Variant data type is the data type for all variables. can contain any kind of data except fixed- ...
- 用户自定义结构数据与VARIANT转换 .
用户自定义结构数据与VARIANT转换 cheungmine 将用户自定义的C结构数据存储成VARIANT类型,需要时再将VARIANT类型转为用户自定义的结构数据,有十分现实的意义,既然我们不想为这 ...
- Boost--variant (C++中的union)
union联合体类型的问题 只能用于内部类型,这使得union在C++中几乎没有用 所以boost提供了variant,相当于是C++中的union #include "boost/vari ...
- Java Algorithm Problems
Java Algorithm Problems 程序员的一天 从开始这个Github已经有将近两年时间, 很高兴这个repo可以帮到有需要的人. 我一直认为, 知识本身是无价的, 因此每逢闲暇, 我就 ...
- 读《Effect Java中文版》
读<Effect Java中文版> 译者序 序 前言 第1章引言 1 第2章创建和销毁对象 4 第1条:考虑用静态工厂方法代替构造函数 4 第2条:使用私有构造函数强化singleto ...
随机推荐
- java设计模式_单例
public class Singleton { public static void main(String[] args) throws Exception { System.out.printl ...
- Learning Cocos2d-x for WP8(4)——中文显示
原文:Learning Cocos2d-x for WP8(4)--中文显示 C#(wp7)兄弟篇Learning Cocos2d-x for XNA(4)——中文显示 Cocos2d-x中文显示,似 ...
- U7Linux文件与目录管理
1. .:代表当前层目录. ..:代表上一层目录. -:代表前一个工作目录. ~:代表目前用户所在的主文件夹. ~account:代表account这个用户的主文件夹. 2.pwd:显示当前目录. p ...
- Git经常使用命令以及使用方法
一 怎样让单个文件回退到指定的版本号 1. 进入到文件所在文件文件夹,或者能找到文件的路径 查看文件的改动记录 git log MainActivity.java 2. 回退到指定的版本号 ...
- vim netrw
我们现在试一下vim文件功能,当你使用vim尝试打开目录时,vim会自动调用netrw.vim插件打开该目录(从操作系统的视角来看,目录其实是一种特殊的文件).例如,我们在vim中执行命令”:e -/ ...
- 深入理解java虚拟机系列(一):java内存区域与内存溢出异常
文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了開始.假设有什么错误或者遗漏,欢迎指出. 一.概述 先上 ...
- Oracle 基于 RMAN 的不完全恢复(incomplete recovery by RMAN)
Oracle 数据库可以实现数据库不完全恢复与完全恢复.完全恢复是将数据库恢复到最新时刻,也就是无损恢复,保证数据库无丢失的恢复.而不完全恢复则是根据需要特意将数据库恢复到某个过去的特定时间点或特定的 ...
- hdu4771 Stealing Harry Potter's Precious
注意--你可能会爆内存-- 假设一个直接爆搜索词-- 队列存储器元件被减少到-- #include<iostream> #include<map> #include<st ...
- Mysql insert声明优化
1) 假设你同一时候从同一客户插入非常多行,使用多个值表的INSERT语句. 这比使用分开INSERT语句快(在一些情况中几倍). Insert into test values(1,2),(1 ...
- Android含文档server结束(client UI接口异步请求的一部分)三
在本文中,AsyncTask为了实现异步请求,详细代码如下所示的: public class downloadActivity extends Activity { private TextView ...