说起来还真是惭愧,如此简单的问题一直就没有太注意。今天偶尔才开始关注。
#include <iostream>
using namespace std;
class CBase
{
public:
CBase()
{
cout<<"I in Base constructor"<<endl;
}
virtual ~CBase()
{
cout<<"I in Base deconstructor"<<endl;
}
};
class CDerived : public CBase
{
public:
CDerived()
{
cout<<"I in CDerived constructor"<<endl;
}
virtual ~CDerived()
{
cout<<"I in CDerived deconstructor"<<endl;
}
};
int main()
{
CBase *pBase = new CDerived();
delete pBase;
return 0;
}
输出结果
I in Base constructor
I in CDerived constructor
I in CDerived deconstructor
I in Base deconstructor
以前一直觉得virtual的指定是可有可无的,现在才知道,如果不制定virutal,那么I in CDerived deconstructor就不会调用。这个与construtor完全不一样,事实上也正是这样把他/它忽略了。
接着就要想想如何实现的呢?
先来看看构造函数
004012CF . 894D F0 mov [ebp-10], ecx
004012D2 . 8B4D F0 mov ecx, [ebp-10]
004012D5 . E8 D0FDFFFF call 004010AA ; 调用基类的构造函数
004012DA . C745 FC 00000>mov dword ptr [ebp-4], 0
004012E1 . 8B45 F0 mov eax, [ebp-10]
004012E4 . C700 3C204300 mov dword ptr [eax], offset CDerived::`vftable'
004012EA . 68 2D104000 push 0040102D
004012EF . 68 1C204300 push 0043201C ; ASCII "I in CDerived constructor"
004012F4 . 68 40954300 push offset std::cout
004012F9 . E8 CAFDFFFF call 004010C8
和以前理解的一样,不多解释
下面是析构函数(注意这里是CDerived生成的delete函数哦)
00401069 . /E9 32040000 jmp CDerived::`scalar deleting destructor'
004014BA |. 894D FC mov [ebp-4], ecx
004014BD |. 8B4D FC mov ecx, [ebp-4]
004014C0 |. E8 F9FBFFFF call 004010BE ; 调用子类的析构函数
004014C5 |. 8B45 08 mov eax, [ebp+8]
004014C8 |. 83E0 01 and eax, 1
004014CB |. 85C0 test eax, eax
004014CD |. 74 0C je short 004014DB
004014CF |. 8B4D FC mov ecx, [ebp-4]
004014D2 |. 51 push ecx ; /Arg1
004014D3 |. E8 A8130000 call operator delete ; \operator delete
0040153F . 894D F0 mov [ebp-10], ecx
00401542 . 8B45 F0 mov eax, [ebp-10]
00401545 . C700 3C204300 mov dword ptr [eax], offset CDerived::`vftable'
0040154B . C745 FC 00000>mov dword ptr [ebp-4], 0
00401552 . 68 2D104000 push 0040102D
00401557 . 68 80204300 push 00432080 ; ASCII "I in CDerived disconstructor"
0040155C . 68 40954300 push offset std::cout
00401561 . E8 62FBFFFF call 004010C8
00401566 . 83C4 08 add esp, 8
00401569 . 8BC8 mov ecx, eax
0040156B . E8 1CFBFFFF call 0040108C
00401570 . C745 FC FFFFF>mov dword ptr [ebp-4], -1
00401577 . 8B4D F0 mov ecx, [ebp-10]
0040157A . E8 E0FAFFFF call 0040105F ; 基类的析构函数
结论:
编译器不能自动识别析构函数,必须要多态的标识。
posted on 2008-05-31 12:32
margin 阅读(185)
评论(0) 编辑 收藏 引用 所属分类:
C/C++