关于虚析构函数,谁能帮我解释一下这个程序的运行结果,谢谢!

xiao7cn 2008-08-08 05:23:51
#include <iostream>

using namespace std;

class Base
{
public:
~Base()
{
fun();
}

virtual void fun()
{
cout<<"Base fun()\n";
}
};

class Derived : public Base
{
public:
virtual void fun()
{
cout<<"Derived fun()\n";
}
};

int main ()
{
Derived b;

return 0;
}
...全文
124 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
太乙 2008-08-19
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 hqin6 的回复:]
引用 10 楼 richbirdandy 的回复:
我想问一句 写这样的程序有什么意义 仅仅是为了测试??

参考Effective C++ 第三版
条款9
绝不要在构造和析构函数中调用virtual函数
结果是未定义的。。。


vs2008,没反应!
[/Quote]

当我没说!

太乙 2008-08-19
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 richbirdandy 的回复:]
我想问一句 写这样的程序有什么意义 仅仅是为了测试??

参考Effective C++ 第三版
条款9
绝不要在构造和析构函数中调用virtual函数
结果是未定义的。。。
[/Quote]

vs2008,没反应!
太乙 2008-08-19
  • 打赏
  • 举报
回复
呵呵,我觉得是什么也不输出!!


因为b在栈上!
stone_clock 2008-08-19
  • 打赏
  • 举报
回复
每个类都有自己的虚函数表(含有虚函数的类),在对象指向谁时,就调用哪个虚函数表,在析构~Base()时,~Derived()已经析构完了,属于Derived类对象的数据已经清除了,此时对象为Base类部分了。看看《C++对象模型》可能会有点帮助。
matrixdwy 2008-08-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yemaoniu 的回复:]
结果是"Base fun()\n"


个人理解 定义一个Derived对象 程序结束后运行 Derived的 默认析构函数 然后 运行Base的析构函数 条用fun() 输出Base fun()\n 请高手指正
[/Quote]
统一
richbirdandy 2008-08-08
  • 打赏
  • 举报
回复
我想问一句 写这样的程序有什么意义 仅仅是为了测试??

参考Effective C++ 第三版
条款9
绝不要在构造和析构函数中调用virtual函数
结果是未定义的。。。
elegant87 2008-08-08
  • 打赏
  • 举报
回复

#include <iostream>

using namespace std;

class Base
{
public:
virtual ~Base()
{
fun();
}

virtual void fun()
{
cout<<"Base fun()\n";
}
};

class Derived : public Base
{
public:
virtual void fun()
{
cout<<"Derived fun()\n";
}
~Derived()
{
fun();
}
};

int main ()
{
Base b;
Derived d;
system("pause");
return 0;
}

虚函数一般在动态连编是用到的,也就是通过基类的指针或者是引用,来访问派生类的继承成员。
对于析构函数来说,一般在基类作为虚函数很有必要,因为派生类的析构函数不负责撤销基类对象的成员。
编译器总是显示的调用派生类的对象基类部分的析构函数。每个析构函数只负责消除自己的成员。
对象的撤销与构造相反。
wfwsm 2008-08-08
  • 打赏
  • 举报
回复
子类对象的析构函数调用时,会自动调用基类的析构函数,调用的顺序和创建对象时构造函数的调用顺序相反
vbanglev 2008-08-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yemaoniu 的回复:]
结果是"Base fun()\n"


个人理解 定义一个Derived对象 程序结束后运行 Derived的 默认析构函数 然后 运行Base的析构函数 条用fun() 输出Base fun()\n 请高手指正
[/Quote]

同意,结果在VC6.0测试下也是相同的,虚函数有自己的对应表不会被后面的fun覆盖
xianyuxiaoqiang 2008-08-08
  • 打赏
  • 举报
回复
偶来学习的。
xiao7cn 2008-08-08
  • 打赏
  • 举报
回复
类Derived的析构函数根本没有被调用!一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。我想所有的C++程序员都知道这样的危险性。当然,如果在析构函数中做了其他工作的话,那你的所有努力也都是白费力气。
所以,文章开头的那个问题的答案就是--这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。
当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。

==================
楼上的,你拷过来这段文字我看过。

但好像说的不是一回事吧。。。。
xiao7cn 2008-08-08
  • 打赏
  • 举报
回复
楼上的,你拷过来这段文字我看过。

但好像说的不是一回事吧。。。。
iu_81 2008-08-08
  • 打赏
  • 举报
回复
子类对象的析构函数调用时,会自动调用基类的析构函数,调用的顺序和创建对象时构造函数的调用顺序相反
yemaoniu 2008-08-08
  • 打赏
  • 举报
回复
结果是"Base fun()\n"


个人理解 定义一个Derived对象 程序结束后运行 Derived的 默认析构函数 然后 运行Base的析构函数 条用fun() 输出Base fun()\n 请高手指正
iu_81 2008-08-08
  • 打赏
  • 举报
回复
类Derived的析构函数根本没有被调用!一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。我想所有的C++程序员都知道这样的危险性。当然,如果在析构函数中做了其他工作的话,那你的所有努力也都是白费力气。
所以,文章开头的那个问题的答案就是--这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。
当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。

64,642

社区成员

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

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