编译器自动创建的析构函数

下面摘自 http://en.cppreference.com/w/cpp/language/destructor

Trivial destructor

The destructor for class T is trivial if all of the following is true:

  • The destructor is not user-provided (meaning, it is implicitly-defined or defaulted)
  • The destructor is not virtual (that is, the base class destructor is not virtual)
  • All direct base classes have trivial destructors
  • All non-static data members of class type (or array of class type) have trivial destructors

A trivial destructor is a destructor that performs no action. Objects with trivial destructors don't require a delete-expression and may be disposed of by simply deallocating their storage. All data types compatible with the C language (POD types) are trivially destructible.

Implicitly-defined destructor

If the implicitly-declared destructor is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. This implicitly-defined destructor has an empty body.

As with any implicitly-defined special member function, the exception specification of the implicitly-defined destructor is non-throwing unless it directly invokes a function with a different exception specification (e.g. when it must call a user-defined destructor for a member or a base subobject with a different exception specification).

trivial destructor 和 implicitly-defined  destructor 都是编译器自动产生的,但是前者在目标文件中不存在,后者在目标文件中存在可以设置断点调试。

先看一段代码:

class A
{
public:
virtual void foo(void) {}
 A* m_ptr;
};


class C
{
int *p;
public:
C() {p = new int;}
~C();
};
C::~C()
{ 
delete p; 
}
 class B : public A
{
public:
virtual void  Bob(){}
C c;
};

int main(void)
{
	B *pB = new B;
	delete pB;
	return 0;
}

用  gdb调试:
(gdb) b B::~B()
Breakpoint 1 at 0x804875e: file test_destructor.cpp, line 22.
(gdb) list 22
17	};
18	C::~C()
19	{ 
20	delete p; 
21	}
22	 class B : public A
23	{
24	public:
25	virtual void  Bob(){}
26	C c;

(gdb) disass B::~B(void)
Dump of assembler code for function B::~B():
   0x08048758 <+0>:	push   %ebp
   0x08048759 <+1>:	mov    %esp,%ebp
   0x0804875b <+3>:	sub    $0x8,%esp
   0x0804875e <+6>:	mov    0x8(%ebp),%eax
   0x08048761 <+9>:	movl   $0x8048820,(%eax)
   0x08048767 <+15>:	mov    0x8(%ebp),%eax
   0x0804876a <+18>:	add    $0x8,%eax
   0x0804876d <+21>:	sub    $0xc,%esp
   0x08048770 <+24>:	push   %eax
   0x08048771 <+25>:	call   0x804865c <C::~C()>
   0x08048776 <+30>:	add    $0x10,%esp
   0x08048779 <+33>:	leave  
   0x0804877a <+34>:	ret    
End of assembler dump.
(gdb) where
#0  C::~C (this=0x804fa18, __in_chrg=<optimized out>) at test_destructor.cpp:20
#1  0x08048776 in B::~B (this=0x804fa10, __in_chrg=<optimized out>) at test_destructor.cpp:22
#2  0x080486b6 in main () at test_destructor.cpp:32
(gdb) 

可以看到,  编译器自动产生的析构函数也调用了  C的析构函数。
$ objdump  -Ct test_destructor  | grep -E  "B\("
08048726  w    F .text	00000032              B::B()
08048758  w    F .text	00000023              B::~B()
08048726  w    F .text	00000032              B::B()
08048758  w    F .text	00000023              B::~B()
$ objdump  -Ct test_destructor  | grep -E  "A\("
08048718  w    F .text	0000000e              A::A()
08048718  w    F .text	0000000e              A::A()
可以看到,目标文件里有 ~C()的符号, 蛋没有  ~A().


Destruction sequence

For both user-defined or implicitly-defined destructors, after the body of the destructor is executed, the compiler calls the destructors for all non-static non-variant members of the class, in reverse order of declaration, then it calls the destructors of all direct base classes in reverse order of construction (which in turn call the destructors of their members and their base classes, etc), and then, if this object is of most-derived class, it calls the destructors of all virtual bases.

Even when the destructor is called directly (e.g. obj.~Foo();), the return statement in ~Foo() does not return control to the caller immediately: it calls all those member and base destructors first.




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值