一个关于虚函数的问题

yufeng1979 2005-03-22 08:34:01
本人在学习C++的虚函数部分时遇到了一个例子:

#include<iostream.h>

class CObject{
public :
virtual void Serialize(){
cout<<"CObject::Serialize()\n\n";
}
};

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

class CMyDoc:public CDocument
{
public :
int m_data2;
virtual void Serialize(){cout<<"CMyDoc::Serialize()\n\n";}
};
void main(){
CMyDoc mydoc;
CMyDoc* pmydoc=new CMyDoc;

cout<<"#1 testing"<<endl;
mydoc.func();

cout<<"#2 testing"<<endl;
((CDocument*)(&mydoc))->func();

cout<<"#3 testing"<<endl;
pmydoc->func();

cout<<"#4 testing"<<endl;
((CDocument)mydoc).func();
}


运行得到的结果是:
#1 testing
CDocument::func()
CMyDoc::Serialize()

#2 testing
CDocument::func()
CMyDoc::Serialize();

#3 testing
CDocument::func()
CMyDoc::Serialize()

#4 testing
CDocument::func()
CDocument::Serialize() <---------对此不解



前面三个我知道为什么是这样的,但是对第四个不太理解,有人能告诉我原因吗?
谢谢
...全文
235 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhousqy 2005-03-23
  • 打赏
  • 举报
回复
对虚函数Serialize的调用只看,调用它的对象或指针所指的对象是什么类型的,你
((CDocument)mydoc).func();
已将mydoc转换成CDocument类型,自是调用CDocument::Serialize()
junmayang 2005-03-23
  • 打赏
  • 举报
回复
学习!
有人能讲清楚吗?》
allen_zhaozhencn 2005-03-23
  • 打赏
  • 举报
回复
((CDocument)mydoc).func(); //首先生成一个临时的CDocument对象,此时,该对象对象的虚函数列表也已经修改。 所以,函数调用时出现的结果也就不言而喻了。
langzi8818 2005-03-23
  • 打赏
  • 举报
回复
这个是侯sir的例子,他后面不是有解释吗?
就是说这是个切割。要调用基类的拷贝构造函数,里面对虚拟指针正确的赋值了,也就是说让它指向了自己的虚拟函数表
yufeng1979 2005-03-23
  • 打赏
  • 举报
回复
"拷贝构造函数一般传递进对象引用"??有谁能给一个拷贝构造函数的实例??谢谢
oyljerry 2005-03-22
  • 打赏
  • 举报
回复
拷贝构造函数一般传递进对象引用
oyljerry 2005-03-22
  • 打赏
  • 举报
回复
拷贝构造函数可以自己重写,如果没有,系统会自动生成一个
yufeng1979 2005-03-22
  • 打赏
  • 举报
回复
拷贝构造函数是不是不应该有参数
dongpy 2005-03-22
  • 打赏
  • 举报
回复
是不是每当使用强制类型转换时都要用到通过拷贝构造函数构造一个临时对象?
======================================
如果是对象之间的强制类型转换,应该是会产生临时对象的。
dongpy 2005-03-22
  • 打赏
  • 举报
回复
拷贝构造函数可以自己改写,如果不改写,编译器会默认生成一个。
yufeng1979 2005-03-22
  • 打赏
  • 举报
回复
拷贝构造函数是编译器自动合成的?还是我们自己可以改写?
yufeng1979 2005-03-22
  • 打赏
  • 举报
回复
再问一个问题
是不是每当使用强制类型转换时都要用到通过拷贝构造函数构造一个临时对象?
oyljerry 2005-03-22
  • 打赏
  • 举报
回复
类型转换了
dongpy 2005-03-22
  • 打赏
  • 举报
回复
通过拷贝构造函数构造了这个临时对象。
dongpy 2005-03-22
  • 打赏
  • 举报
回复
VC6下:

CMyDoc mydoc;
==============================================================
004010B8 lea ecx,[ebp-0Ch]
004010BB call @ILT+55(CMyDoc::CMyDoc) (0040103c)

34: ((CDocument)mydoc).func();
===============================================================
004010C0 lea eax,[ebp-0Ch]
004010C3 push eax
004010C4 lea ecx,[ebp-14h] //产生临时对象
004010C7 call @ILT+75(CDocument::CDocument) (00401050) //构造临时对象
004010CC mov ecx,eax //临时对象的this指针
004010CE call @ILT+35(CDocument::func) (00401028)
yufeng1979 2005-03-22
  • 打赏
  • 举报
回复
如何产生这个临时对象
dongpy 2005-03-22
  • 打赏
  • 举报
回复
(CDocument)mydoc这里产生了CDocument类型的临时对象。
yufeng1979 2005-03-22
  • 打赏
  • 举报
回复
我的意思是C++编译器为了实现动态绑定,每个内含虚函数的类编译器都会为它做出一个虚函数表,表中的元素指向虚函数的地址,同时编译器会为类加上一个成员变量来指向该函数表.那么当把mydoc转换成CDocument类型时,它的指向函数表的指针的值是如何被编译器改变的
1982pc 2005-03-22
  • 打赏
  • 举报
回复
你已经把mydoc强行转化为CDocument当然就是调用CDocument相应的成员函数
yufeng1979 2005-03-22
  • 打赏
  • 举报
回复
那么,编译器是如何实现将mydoc转换成CDocument?
加载更多回复(1)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧