首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

请教父类与子类的析构函数顺序

2012-10-11 
请问父类与子类的析构函数顺序?子类生成对象时 是先调用父类的构造函数再调用自己的构造函数析构时的顺序

请问父类与子类的析构函数顺序?
子类生成对象时 是先调用父类的构造函数 再调用自己的构造函数

析构时的顺序是怎样的? 比如下面

#include <iostream>
using namespace std;
class A{
public:
  A(){cout<<"Construct a"<<endl;p();}
  virtual void p(){cout<<"A"<<endl;}
  ~A(){cout<<"Destruct a"<<endl;p();}  
};
class B : public A{
public:
  B(){cout<<"Construct b"<<endl;p();}
  void p(){cout<<"B"<<endl;}
  ~B(){cout<<"Destruct b"<<endl;p();}  
};
int main()
{
  A *a=new B();
  delete a;
  getchar();
  return 0;
}




打印的结果是:
Construct a
A
Construct b
B
Destruct a
A



也就是说 生成子类对象时 先调用父类的构造函数 再调用自己的构造函数

析构时 就直接调用父类的析构函数了 ?



[解决办法]
a指向A对象,而且析构函数不是虚拟函数,不会调用子类B析构函数
[解决办法]
这个 和你的 A *a=new B(); 
有关 

如果你用 B *a=new B(); 
的话 出现的就是 先 析构 B类 再析构A类 
Construct a 

Construct b 

Destruct b 

Destruct a 



这个是和执行指向有关的 具体可以看看 关于类继承方面的书的
[解决办法]
A *a = new B;
a的类型是A;
delete a时将调用类型A的析构函数;

如果A的析构函数是虚函数,则:
delete a时调用类型A的析构函数步骤如下:
1,到虚函数映射表中查找A的实际析构函数;
2,发现被实例化为B的析构函数;
3,调用B的析构函数;
4,调用A的析构函数---如果A的析构不是纯虚函数的话。
[解决办法]
先子类再父类 这和构造顺序相反
[解决办法]
A *a=new B(); 
虽然指针a指向B类型,但指针a的类型是A
所以析构的时候只调用A的析构函数
如果把声明虚析构函数,就可以调用子类B的析构函数了。这就是所谓的后绑定。
[解决办法]
先构造的后析构
如果基类任何一个构造失败,所有的子类都失败。
[解决办法]
析构函数最好都写成虚的。这就是最好的例子。
[解决办法]

探讨
这个 和你的 A *a=new B();
有关

如果你用 B *a=new B();
的话 出现的就是 先  析构 B类 再析构A类
Construct a
A
Construct b
B
Destruct b
B
Destruct a
A


这个是和执行指向有关的  具体可以看看 关于类继承方面的书的

[解决办法]
探讨
这个 和你的 A *a=new B();
有关

如果你用 B *a=new B();
的话 出现的就是 先  析构 B类 再析构A类
Construct a
A
Construct b
B
Destruct b
B
Destruct a
A


这个是和执行指向有关的  具体可以看看 关于类继承方面的书的

[解决办法]
析构函数要是virtual
[解决办法]
我看大家都说的不错,对于上述情况A *a=new B(); a是指向A的,所以只需调用A的析构函数.
[解决办法]
生成子类对象时,先调用父类的构造函数,再调用自己的构造函数 
析构时是先调用子类的析构函数,再调用父类的析构函数
之所以出现你的现象,是因为
A *a=new B(); 
delete a;
这种用法是不妥的,你这样做只是析构了父类对象,而并没有删除子类对象.
改为这样
A *a=new B(); 
delete (B*)a; 看看结果你就清楚了.

一般遇到这样的现象,需要将基类的析构函数定义为虚拟的.

#include <iostream> 
using namespace std; 
class A{ 


public: 
A(){cout < <"Construct a" < <endl;p();} 
virtual void p(){cout < <"A" < <endl;} 
virtual ~A(){cout < <"Destruct a" < <endl;p();}
}; 
class B : public A{ 
public: 
B(){cout < <"Construct b" < <endl;p();} 
void p(){cout < <"B" < <endl;} 
~B(){cout < <"Destruct b" < <endl;p();}
}; 
int main() 

A *a=new B(); 
delete a; 
getchar(); 
return 0; 



打印的结果是: 
Construct a 

Construct b 

Destruct b
B
Destruct a
A
[解决办法]
析构函数执行顺序是和构造函数相反的。先子类后父类。

基类的析构函数要定义成虚函数。

楼主的程序已经内存泄露了。。。
[解决办法]
建议lz找一本effictive c++看,里面有一条是专门讲解基类析构函数为什么应该是virtual
[解决办法]
你的析构函数不是虚函数
delete a的时候就不会调用子函数的析构函数


引用楼主 wilbur512 的帖子:
子类生成对象时 是先调用父类的构造函数 再调用自己的构造函数

析构时的顺序是怎样的? 比如下面

#include <iostream>
using namespace std;
class A{
public:
A(){cout < <"Construct a" < <endl;p();}
virtual void p(){cout < <"A" < <endl;}
~A(){cout < <"Destruct a" < <endl;p();}
};
class B : public A{
public:
B(){cout < <"Construct b" < <endl;p();}


[解决办法]
析构的顺序与构造函数的相反!

热点排行