学习笔记:候捷深入浅出MFC第二章

#include "stdafx.h"


class CObject
{
public:
    
virtual void Serialize()
    
{
        cout
<<"CObject::Serialize()\n\n";
    }
;
}
;
class CDocument:public CObject
{
public:
    
int m_data1;
    
void func()
    
{
        cout
<<"CDocment::func()"<<endl;
        Serialize();
    }

    
virtual void Serialize()
    
{
        cout
<<"CDocument::Serialize()"<<endl;
    }
;
}
;
class CMyDoc:public CDocument
{
public:
    
int m_data2;
    
virtual void Serialize()
    
{
        cout
<<"CMyDoc::Serialize()"<<endl;
    }

}
;
int _tmain(int argc, _TCHAR* argv[])
{
    CMyDoc mydoc;
    CMyDoc 
* pmydoc=new CMyDoc;
    cout
<<"#1"<<endl;
    mydoc.func();
    cout
<<"#2 testing"<<endl;
    ((CDocument
*)(&mydoc))->func();
    cout
<<"#3 testing"<<endl;
    pmydoc
->func();
    cout
<<"#4 testing"<<endl;
    ((CDocument)mydoc).func();
    
return 0;
}

这段代码的输出是:
#1
CDocment::func()
CMyDoc::Serialize()
#2 testing
CDocment::func()
CMyDoc::Serialize()
#3 testing
CDocment::func()
CMyDoc::Serialize()
#4 testing
CDocment::func()
CDocument::Serialize()  ------>注意这里

其它的调用都符合多态的规则,注意到#2和#4都是类型的强制转换.但#2是对指针类型的转换,#4是对实例的转换.候捷在书上是这样说的:
所谓的"向上类型转换"将会造成对象的内容被切割:当我们调用这个方法时,mydoc已经是半条命对象了,而func内部调用的虚函数Serialize后者将使用"mydoc"的虚函数指针,虽然存在,但值是什么呢?幸运的是,由于 ((CDocument)mydoc).func();是转值而非传址操作,编译器以所谓的拷贝构造函数把Cdocument对象内容复制了一份,使得mydoc的vtable(虚函数表)与CDocument对象的相同.例子中没有使用拷贝构造函数,但编译器会自动合成一个.这相对于 ((CDocument)mydoc)实际上是返回了一个CDocument的新对象.

posted @ 2007-06-16 15:56  吴东雷  阅读(579)  评论(0编辑  收藏  举报