请问一个C++的虚函数在析构函数中执行的有关问题
请教一个C++的虚函数在析构函数中执行的问题
如上面的代码,运行后打印的结果是:
call CDerived::fun
call CBase::fun
这是为什么啊?
我希望总是调用派生类的fun,但不希望在派生类的析构函数显示调用call。
------解决方案--------------------
virtual ~CBase()
的时候,CDerived已经析构了。
构造的时候,先父类再子类,析构的时候,先子类再父类。
------解决方案--------------------
印象中effectvie C++中有说,尽量不要在析构函数中调用虚函数
------解决方案--------------------
楼主这是基础吧。
不过面试都玩这个,建议先看钱能的那本C++,然后再看Primer。
构造的时候,先父类再子类,析构的时候,先子类再父类。
楼主我觉得你如果明白继承关系的话,父类和子类的内存中的存储关系,你一定对这个问题了如指掌。
从根源了解问题,比别人告诉你规则好。
------解决方案--------------------
转换是不管用的,C++的RTTI就是转换对于虚函数也无效,虚函数依赖的是虚函数表,是运行期决定的,与静态编译无关
析构后再赋值是不可靠的,析构后就会从栈上释放那块内存,虽然能够成功,只是这块内存刚好还没被用到,再定义变量就可能覆盖这块内存
------解决方案--------------------
的确是啊
delete p分两步走
先是删除派生类的数据成员和成员函数
等派生类部分的内容被删除之后
这个派生类对象其实就变成了基类对象了
所以最后执行的是基类的fun
------解决方案--------------------
我是来散步的,顺便拐点分~
- C/C++ code
#include <stdio.h> #include <stdlib.h> class CBase { public: virtual ~CBase() { fun(); } void call() { fun(); } protected: virtual void fun() { printf("call CBase::fun\n"); } }; class CDerived:public CBase { public: virtual ~CDerived() { // call(); 这里不调用call,就不会调用到派生类的fun } protected: virtual void fun() { printf("call CDerived::fun\n"); } }; int main() { CDerived *p=new CDerived; p->call(); delete p; }
如上面的代码,运行后打印的结果是:
call CDerived::fun
call CBase::fun
这是为什么啊?
我希望总是调用派生类的fun,但不希望在派生类的析构函数显示调用call。
------解决方案--------------------
virtual ~CBase()
的时候,CDerived已经析构了。
构造的时候,先父类再子类,析构的时候,先子类再父类。
------解决方案--------------------
印象中effectvie C++中有说,尽量不要在析构函数中调用虚函数
------解决方案--------------------
楼主这是基础吧。
不过面试都玩这个,建议先看钱能的那本C++,然后再看Primer。
构造的时候,先父类再子类,析构的时候,先子类再父类。
楼主我觉得你如果明白继承关系的话,父类和子类的内存中的存储关系,你一定对这个问题了如指掌。
从根源了解问题,比别人告诉你规则好。
------解决方案--------------------
转换是不管用的,C++的RTTI就是转换对于虚函数也无效,虚函数依赖的是虚函数表,是运行期决定的,与静态编译无关
析构后再赋值是不可靠的,析构后就会从栈上释放那块内存,虽然能够成功,只是这块内存刚好还没被用到,再定义变量就可能覆盖这块内存
------解决方案--------------------
的确是啊
delete p分两步走
先是删除派生类的数据成员和成员函数
等派生类部分的内容被删除之后
这个派生类对象其实就变成了基类对象了
所以最后执行的是基类的fun
------解决方案--------------------
我是来散步的,顺便拐点分~