构造函数,析构函数

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

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

#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



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

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

 
 
  • yyyapple用户头像
  • yyyapple
  • (会用牙刷的鱼)
  • 等 级:
#1楼 得分:2回复于:2008-09-27 09:43:25
a指向A对象,而且析构函数不是虚拟函数,不会调用子类B析构函数
 
#2楼 得分:3回复于:2008-09-27 09:49:04
这个 和你的 A *a=new B();  
有关  

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


这个是和执行指向有关的 具体可以看看 关于类继承方面的书的
 
  • Canvas用户头像
  • Canvas
  • (霜有棱,天无情 - 天下无霜)
  • 等 级:
#3楼 得分:2回复于:2008-09-27 10:03:49
A *a = new B;
a的类型是A;
delete a时将调用类型A的析构函数;

如果A的析构函数是虚函数,则:
delete a时调用类型A的析构函数步骤如下:
1,到虚函数映射表中查找A的实际析构函数;
2,发现被实例化为B的析构函数;
3,调用B的析构函数;
4,调用A的析构函数---如果A的析构不是纯虚函数的话。
 
  • chlaws用户头像
  • chlaws
  • (潇洒哥说-你是石家-)
  • 等 级:
#4楼 得分:1回复于:2008-09-27 10:04:30
先子类再父类 这和构造顺序相反
 
#5楼 得分:1回复于:2008-09-27 10:14:31
A *a=new B();  
虽然指针a指向B类型,但指针a的类型是A
所以析构的时候只调用A的析构函数
如果把声明虚析构函数,就可以调用子类B的析构函数了。这就是所谓的后绑定。
 
#6楼 得分:1回复于:2008-09-27 10:38:42
先构造的后析构
如果基类任何一个构造失败,所有的子类都失败。
 
#7楼 得分:1回复于:2008-09-27 10:48:42
析构函数最好都写成虚的。这就是最好的例子。
 
#8楼 得分:1回复于:2008-09-27 11:02:19
引用 2 楼 rollrock1987 的回复:
这个 和你的 A *a=new B(); 
有关 

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

Construct b 

Destruct b 

Destruct a 



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


同意之!
 
#9楼 得分:1回复于:2008-09-27 11:50:21
引用 2 楼 rollrock1987 的回复:
这个 和你的 A *a=new B();
有关

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


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


正是这样~~
 
#10楼 得分:1回复于:2008-09-27 11:51:39
析构函数要是virtual
 
  • mengde007用户头像
  • mengde007
  • (偶要成为高手 )
  • 等 级:
#11楼 得分:1回复于:2008-09-27 12:53:31
我看大家都说的不错,对于上述情况A *a=new B(); a是指向A的,所以只需调用A的析构函数.
 
#12楼 得分:1回复于:2008-09-27 13:23:14
生成子类对象时,先调用父类的构造函数,再调用自己的构造函数  
析构时是先调用子类的析构函数,再调用父类的析构函数
之所以出现你的现象,是因为
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  
A  
Construct b  
B  
Destruct b 

Destruct a 
A
 
  • bluecll用户头像
  • bluecll
  • (juliuschen.com)
  • 等 级:
#13楼 得分:1回复于:2008-09-27 13:39:21
析构函数执行顺序是和构造函数相反的。先子类后父类。

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

楼主的程序已经内存泄露了。。。
 
#14楼 得分:1回复于:2008-09-29 22:43:04
建议lz找一本effictive c++看,里面有一条是专门讲解基类析构函数为什么应该是virtual
 
#15楼 得分:1回复于:2008-09-29 23:46:38
你的析构函数不是虚函数
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();} 

 
#16楼 得分:1回复于:2008-09-30 09:02:07
析构的顺序与构造函数的相反!
 
  • gotope用户头像
  • gotope
  • (gotope)
  • 等 级:
#17楼 得分:0回复于:2011-10-19 15:24:23
是否尽量的基类析构函数都写为virtual?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值