学习笔记:候捷深入浅出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的新对象.
一点说明:为什么在标题中要嵌入英文?原因是为了能够让国外的网友能查询到这篇文章。平常在Google上查资料的时候,经常参考国外网友的博客,帮助我解决了很多问题,所以我也想让他们能够参考我写的内容。当然文中我不可能全部译为英文,所以我尽量把代码粘全,靠代码说话吧。



浙公网安备 33010602011771号