问个关于虚析构函数问题,不是很懂

a2471388918 2013-07-16 09:12:03
#include <iostream>
using namespace std;

class Base {
public:
virtual~Base();
};
Base::~Base(){
cout<<"Base destructor "<<endl;
}

class Derived :public Base {
public:
Derived ();
~Derived();
private:
int *p;
};
Derived::Derived(){
p=new int(0);
}
Derived::~Derived(){
cout<<"Derived destructor "<<endl;
delete p;
}
void fun(Base*b){
delete b;
}
int main(){
Base *b=new Derived ();
fun(b);
return 0;
}






结果不是很明白,首先这里调用了Devired的析构函数,证明那个new Derived ();调用了Derived的构造函数,new不是开辟了用来存储后面数类型的空间,然后返回地址给左边那个吗,为什么还要初始化的(现在看国产书,没说);
还有,既然那个 virtual~Base();是虚的,那应该只调用~Derived()啊,为什么后来还调用了~Base();
大神出来吧!我是新手!
...全文
196 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaohuh421 2013-07-18
  • 打赏
  • 举报
回复
虚函数的作用楼主是知道的吧. 虚析构函数的作用跟虚函数一样, 只是有点区别, 虚析构函数会自动调用基类的函数, 普通虚函数不会.
lm_whales 2013-07-18
  • 打赏
  • 举报
回复
虚析构函数,是用在多态上的,用了来保证,delete 基类指针指向的派生类对象时,能够正确析构子类对象的。delete 会调用 析构函数 比如 class Base{ virtual ~Base(){};//<==> virtual void dtor(){}; }; class Derived{ virtual ~Derived(){}; //<==>virtual void dtor(){}; } Base *pBase =new Derived; delete pBase;//<==>{ pBase->detor(); operator delete(pBase);} <==> {pBase->~Derived();operator delete(pBase);} PS: 派生类对象析构时,会自动调用,基类对象的,析构函数--在子类析构函数,内部的代码,执行完成以后。 可以把析构函数看成是,特殊的重载函数,虽然函数名称不同。 这样在虚函数表中,派生类的析构函数,和父类的析构函数的位置,是相同的; 派生类对象的,虚函数表里的,析构函数位置,存放的是派生类的,析构函数。 所以 delete时, 通过定义,虚析构函数,如果基类指针,指向派生类对象的话,会调用派生类的析构函数。 派生类的析构函数结束时,会调用基类的析构函数; 派生类对象,和相应的基类对象,都得以析构。 如果不是虚析构函数,delete时,会直接析构基类对象,导致派生类对象的,派生类定义部分,没有析构。 产生不能完全析构的错误。
漫步者、 2013-07-16
  • 打赏
  • 举报
回复
引用 2 楼 a2471388918 的回复:
引用 1 楼 ganpengjin1 的回复:
析构顺序和你的构造顺序相反
不给分你
又不是来找你要分的,觉得说的不对,可以无视的
a2471388918 2013-07-16
  • 打赏
  • 举报
回复
引用 3 楼 haomingzidoumeilea 的回复:
参考:http://blog.csdn.net/songthin/article/details/1703966 new分三步:动态开辟空间,调用构造函数,返回对应指针 因为~Drived()只析构子类的部分,还要~Base()来析构继承父类的部分.和构造函数正好顺序相反。
我在德问找到答案了,原来是说继承的时候会构造基类的,所以还会调用析构,对吧
a2471388918 2013-07-16
  • 打赏
  • 举报
回复
引用 6 楼 ananluowei 的回复:
没有virtual,是按照指针的类型来析构,在这个多态的例子中,是析构~Base()而不析构~Derived() 有virtual,是按照指针指向的对象类型来析构,这个例子中是析构~Derived() 对于派生类来说,析构是从自己往基类一层层析构的,所以还会析构~Base() 你可以去掉基类析构的virtual再运行,结果只会有 Base destructor
我在德问找到答案了,原来是说继承的时候会构造基类的,所以还会调用析构,对吧
max_min_ 2013-07-16
  • 打赏
  • 举报
回复
构造 是 先父后子, 析构是先子后父
大尾巴猫 2013-07-16
  • 打赏
  • 举报
回复
没有virtual,是按照指针的类型来析构,在这个多态的例子中,是析构~Base()而不析构~Derived() 有virtual,是按照指针指向的对象类型来析构,这个例子中是析构~Derived() 对于派生类来说,析构是从自己往基类一层层析构的,所以还会析构~Base() 你可以去掉基类析构的virtual再运行,结果只会有 Base destructor
alexandnpu 2013-07-16
  • 打赏
  • 举报
回复
不太明白你的第一个问题, 简单来说,new 操作符有两个动作,1,分配内存;2在那个内存上调用构造函数。 对于第二个问题: 析构函数是个特殊的函数,在多态delete时候,这个是要保证父类的析构函数也要调用的。 (不知道这个是不是在标准里就定义好了的。)
Jhon_Easter 2013-07-16
  • 打赏
  • 举报
回复
基类应具有析构函数,以保证在删除指向动态分配对象的指针时,根据指针实际指向的对象所属的类型运行适当的析构函数。 上述代码中,将基类的析构函数定义为虚函数,这使得在delete指向派生类对象的指针时首先调用派生类的析构函数,再调用基类的析构函数,从而实现完整释放。 若不定义为虚函数,则存在内存未完全delete的问题。
haomingzidoumeilea 2013-07-16
  • 打赏
  • 举报
回复
参考:http://blog.csdn.net/songthin/article/details/1703966 new分三步:动态开辟空间,调用构造函数,返回对应指针 因为~Drived()只析构子类的部分,还要~Base()来析构继承父类的部分.和构造函数正好顺序相反。
a2471388918 2013-07-16
  • 打赏
  • 举报
回复
引用 1 楼 ganpengjin1 的回复:
析构顺序和你的构造顺序相反
不给分你
漫步者、 2013-07-16
  • 打赏
  • 举报
回复
析构顺序和你的构造顺序相反

64,637

社区成员

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

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