VC中的对象建模与表达之对象类型转换2

以下内容节选自新作《把脉VC++》

电子工业出版社出版

书接上文

4.2.3 向上转换与向下转换

向上转换(upcast,派生类转换成基类)总是隐含的进行,派生类总是能够转换成基类的引用类型,如:

 
CDialog dlg;
CButton btn;
 
CWnd & wnd1 = dlg;
CWnd & wnd2 = btn;
 
有的时候,我们可能已经知道当前指针所指向的对象到底是什么类型,那么可以使用强制转换完成向下转换(downcast):
 
CDialog & dlg2 = (CDialog &)wnd1;
CButton & btn2 = (CButton &)wnd2;
 
向下转换必须是以显式的方式向编译器提出,当然了,向下转换具有一定的风险,如果给定的基类指针并非指向一个派生类对象,那么,将它强制进行向下转换,其结果是不可预料的!如下代码:
 
CDialog & dlg2 = (CDialog &)wnd2;
dlg2.DoModal();
 
这样的代码肯定会报错。
 
4.2.4     变体VARIANT
熟悉javascript或者vbscript语言的程序员可能知道,在这些脚本语言中使用变量真的很简单:
 

【程序 4? 4】javascript中的对象类型
 
01            <script>
02               var i = 100;    //i 是一个整数
03               alert(i + 10);
04               i = "100";      //i 现在是一个字符串
05               alert(i + 10);
06            </script>

 
光盘导读
该项目对应于光盘中的目录“/ch04/var.html”。
如上脚本在IE浏览器中会弹出如下两个不同对话框:
 

4? 6         javascript脚本运行结果

由于javascript语言不是强类型的语言,所以它不需要明确每个变量的真实类型。var即表明i为一个变量,至于它的类型,并未指定。这个i就是变体。
目前计算机语言多种多样,如C++、Java、Basic、Pascal等,此外还有javascript、VBScript、ActionScript等脚本语言,它们各自维护自己的数据类型,当使用C++这样强类型的语言来读取数据库或者与其它语言之间来交换数据时,它很有可能不知道获取到的数据的具体类型,这个时候必须借助于变体类型读取数据。VARIANT数据类型就具有跨语言的特性,同时它可以表示(存储)任意类型的数据。其定义:
 
typedef tagVARIANT VARIANT;
typedef struct tagVARIANT VARIANTARG;
 
从C++语言的角度来讲,VARIANT 其实是一个结构,结构中用一个vt成员表示数据的类型,同时真正的数据则存储在union空间中。一般我们使用VARIANT的步骤为:
(1)      定义一个VARIANT变量,如:var;
(2)      通过vt成员设定VARIANT变量的数据类型,如:var.vt = VT_I4;
(3)      通过对应的union成员设定数据内容,如:var.lVal = 100;
综上所属,利用VARIANT表示一个整型数据:
 
VARIANT var;
var.vt = VT_I4;      //指明整型数据
var.lVal = 100;      //赋值
 
利用VARIANT表示一个布尔值:
 
VARIANT var;
var.vt = VT_BOOL;                //指明整型数据
var.boolVal = VARIANT_TRUE; //赋值
 
利用VARIANT保存一个字符串:
 
VARIANT var;
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(L"hello, world!");
 
根据以上的代码,可以想象,VARIANT的定义可能类似于如下:
 
struct VARIANT
{
    VARTYPE vt;                     //数据类型
    union
    {
        LONG            lVal;       // VT_I4
        VARIANT_BOOL    boolVal     // VT_BOOL
        BSTR            bstrVal;    // VT_BSTR
    }
};
 
实际上,VARIANT的定义就是这样的,只不过由于它需要支持的类型太多,所以它包含的联合成员会更多。限于篇幅,在此不再附出。
VARIANT支持的类型,也就是vt成员的取值如表 4? 3所示。
4 ? 3 VARIANT支持的类型
类型名
含义
VT_EMPTY
指示未指定值
VT_NULL
指示空值(类似于 SQL 中的空值)
VT_I2
指示 short 整数
VT_I4
指示 long 整数
VT_R4
指示 float
VT_R8
指示 double
VT_CY
指示货币值
VT_DATE
指示 DATE
VT_BSTR
指示 BSTR 字符串
VT_DISPATCH
指示 IDispatch 指针
VT_ERROR
指示 SCODE
VT_BOOL
指示一个布尔值
VT_VARIANT
指示 VARIANTfar 指针
VT_UNKNOWN
指示 IUnknown 指针
VT_DECIMAL
指示 decimal
VT_I1
指示 char
VT_UI1
指示 byte
VT_UI2
指示 unsignedshort
VT_UI4
指示 unsignedlong
VT_I8
指示 64 位整数
VT_UI8
指示 64 位无符号整数
VT_INT
指示整数值
VT_UINT
指示 unsigned 整数值
VT_VOID
指示 C 样式 void
VT_HRESULT
指示 HRESULT
VT_PTR
指示指针类型
VT_SAFEARRAY
指示 SAFEARRAY
VT_CARRAY
指示 C 样式数组
VT_USERDEFINED
指示用户定义的类型
VT_LPSTR
指示一个以 NULL 结尾的字符串
VT_LPWSTR
指示由 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing 终止的宽字符串
VT_RECORD
指示用户定义的类型
VT_FILETIME
指示 FILETIME
VT_BLOB
指示以长度为前缀的字节
VT_STREAM
指示随后是流的名称
VT_STORAGE
指示随后是存储的名称
VT_STREAMED_OBJECT
指示流包含对象
VT_STORED_OBJECT
指示存储包含对象
VT_BLOB_OBJECT
指示 Blob 包含对象
VT_CF
指示剪贴板格式
VT_CLSID
指示类 ID
VT_VECTOR
指示简单的已计数数组
VT_ARRAY
指示 SAFEARRAY 指针
VT_BYREF
指示值为引用

未完待续...

 

欢迎参加新作《代码揭秘》的有奖书评征集活动,读书有感,即可获赠博文视点精品图书一套,详情请至http://www.broadview.com.cn/zhuanti/daimajiemi/introduction.html

----------------------------------------------------

如果你想同我交流,欢迎点击链接http://student.csdn.net/invite.php?u=113322&c=a139a65a1494291d和我成为好友!

 
 
 
 
 
 
 
 
 
 
 
 

你可能感兴趣的:(VC中的对象建模与表达之对象类型转换2)