zoukankan      html  css  js  c++  java
  • 从Java到C++——从union到VARIANT与CComVariant的深层剖析

    版权声明:本文为博主原创文章,未经博主同意不得用于不论什么商业用途。转载请注明出处。 https://blog.csdn.net/luoweifu/article/details/35797455

          我第一次用VARIANTCComVariant的时候全然不明确它是怎么回事。为它什么数据类型都能够存放,什么数据都能够被能够初始化?里面究竟是怎么实现的?感觉又奇妙又迷惑。我们在上一节中讲了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的结构能够參考头文件VC98IncludeOAIDL.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的结构能够參考头文件VC98IncludeOAIDL.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的结构能够參考头文件VC98IncludeOAIDL.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的结构能够參考头文件VC98IncludeOAIDL.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




  • 相关阅读:
    multipart/form-data
    Java面试之SE基础基本数据类型
    数据库中的悲观锁和乐观锁详解
    j2SE基回顾(一)
    Hibernate 检索查询的几种方式(HQL,QBC,本地SQL,集成Spring等)
    消防(bzoj 2282)
    YY的GCD(bzoj 2820)
    Problem b(bzoj 2301)
    完全平方数(bzoj 2440)
    The Luckiest number(hdu 2462)
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/9958675.html
Copyright © 2011-2022 走看看