woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

C++构造函数的幕后工作

多年前学习C++的时候就知道每个类都有一个默认的构造函数,但是为什么要有这样的规则却一直不求甚解,汗一个。刚好最近在重新学习C++的内存模型,看看它到底做了么事?

写一个简单的类:

class CParentA

{

public:

   CParentA() {}

 

public:

   int parenta_a;

   int parenta_b;

 

public:  

   virtual void parenta_f1() {this->parenta_a = 0x10;}

   virtual void parenta_f2() {this->parenta_a = 0x20;}

 

public:  

   void parenta_f3() {this->parenta_a = 0x30;}

   void parenta_f4() {this->parenta_a = 0x40;}

};

看看构造函数的汇编代码:

   CParentA() {}

00401330 55               push        ebp 

00401331 8B EC            mov         ebp,esp

00401333 51               push        ecx 

00401334 89 4D FC         mov         dword ptr [ebp-4],ecx

00401337 8B 45 FC         mov         eax,dword ptr [this]

0040133A C7 00 60 68 40 00 mov         dword ptr [eax],offset CParentA::`vftable' (406860h)

00401340 8B 45 FC         mov         eax,dword ptr [this]

00401343 8B E5            mov         esp,ebp

00401345 5D               pop         ebp 

00401346 C3               ret             

从这里发现了两行很有意思的代码:

00401337 8B 45 FC         mov         eax,dword ptr [this]

0040133A C7 00 60 68 40 00 mov         dword ptr [eax],offset CParentA::`vftable' (406860h)

我们知道在有vtbl的情况下,this指向的前四个字节用来存放vtbl的指针。原来在构造函数里还有一个工作是要设置vtbl的指针。难怪C++非要在里面插入一个构造函数。

删除我们自己写的构造函数,再构造一个CParentA的对象。

   CParentA pa;

0040111E 8D 4D F0         lea         ecx,[pa]

00401121 E8 39 FF FF FF   call        CParentA::CParentA (40105Fh)

还是要调用CParentA::CParentA,看看它做了什么:

CParentA::CParentA:

004013D0 55               push        ebp 

004013D1 8B EC            mov         ebp,esp

004013D3 51               push        ecx 

004013D4 89 4D FC         mov         dword ptr [ebp-4],ecx

004013D7 8B 45 FC         mov         eax,dword ptr [this]

004013DA C7 00 60 68 40 00 mov         dword ptr [eax],offset CParentA::`vftable' (406860h)

004013E0 8B 45 FC         mov         eax,dword ptr [this]

004013E3 8B E5            mov         esp,ebp

004013E5 5D               pop         ebp 

004013E6 C3               ret             

比较两个构造函数的汇编代码可以发现,它们并没有什么不同。

那么,假如一个类没有虚函数,也就没有vtbl,那么它是不是就不需要生成构造函数了呢?试试将CParentA里面的两个虚函数去掉:

   CParentA pa;

 

可以发现,这行代码果然不再生成对构造函数的调用!

 

posted on 2009-09-21 10:26 肥仔 阅读(369) 评论(0)  编辑 收藏 引用 所属分类: C++ 基础


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理