c++构造函数的背后

原创 2005年04月27日 11:25:00

OS winxp 、平台:i386

/*

* 以下是测试代码

*/

/*


* class obj 
*/
class obj
{
public:
     int m_i;
     int *m_pi;
     obj(int *ptemp)
     {

        printf("this point to %x/n" , (unsigned int)this );
        m_i = 0;
        printf("address of m_i = %x/n" , (unsigned int)&m_i );
        this->m_pi = ptemp;
        printf("address of m_pi = %x/n" , (unsigned int)&m_pi);
     }
     void funcA()
    {
         printf("this is funcA/n");
    }
 
    void funcB()
   {
        printf("this is funcB/n");
   }
   virtual void vfunc()
   {
        printf("this is virtual func");
   }
   ~obj()
   {
   }
};

/* main */

  int main(int arg , char *argv[])

  {

  int n = 2 ;
  obj *po = new obj(&n);
  cout<<"***after construt***"<<endl;
  printf("address of po = %x " , (unsigned int)po );
  cout<<po->m_i<<endl;
  cout<<*po->m_pi<<endl; 
  delete po ;

}

1.初始化过程:

我们知道类的对象初始化需要调用类的构造函数。那么这个过程是怎么样的呢?我们先来看看对象的初始化过程。 

(一) obj *po new obj(&n) ;

对应汇编:

00401C23 0F BF 0D 5C 55 41 00    movsx       ecx,word ptr [`main'::`2'::__LINE__Var (0041555c)]

00401C2A 83 C1 11                         add         ecx,11h

00401C2D 51                                   push        ecx

00401C2E 68 20 55 41 00             push        offset THIS_FILE (00415520)

00401C33 6A0C                              push        0Ch

00401C35 E8 80 FB FF FF              call        operator new (004017ba)/*1 调用operator newnew操作符)分配了sizeof(obj)大小的内存空间。*/

00401C3A 83 C4 0C                        add         esp,0Ch

00401C3D 89 45 E0                         mov         dword ptr [ebp-20h],eax    /*2.eax中保存了返回的内存起始地址指针,此处把起始地址指针保存在[ebp-20h]中。现在我们记住eax的值,我这里是0x00421110,后面有用*/

00401C40 C7 45 FC 00 00 00 00    mov         dword ptr [ebp-4],0

00401C47 83 7D E0 00                   cmp         dword ptr [ebp-20h],0    /*3 这里判断分配的地址是否为空,和我们通常在分配完内存后所作的判断一样*/

00401C4B 74 11                              je          main+12Eh (00401c5e)

00401C4D 8D 55 EC                       lea         edx,[n]

00401C50 52                                  push      edx    /*obj的构造函数的参数入栈,为调用构造函数作准备*/

00401C51 8B 4D E0                       mov       ecx,dword ptr [ebp-20h]

/*参数保存在寄存器cx*/

00401C54 E8 D4 F3 FF FF            call        @ILT+40(obj::obj) (0040102d) /*呵呵,开始了。进入obj构造函数的调用*/

 我们仍然来看能给我们提示的关键语句:

(二)printf("this point to %x/n" , (unsigned int)this );

00401A91 8B F4                             mov         esi,esp

00401A93 8B 55 FC                        mov         edx,dword ptr [ebp-4]

00401A96 52                                   push        edx

00401A97 68 6C 41 41 00               push        offset string "this point to %x/n" (0041416c)

/*按函数调用方式__cdecl ,参数(unsigned int)this)先入栈,在我这里,从memory中可以看到ebp-4 = 12fee4 ,[ebp-4] = 421110 ,这就是前面通过operator new分配的内存首址,也就是说obj *po此时指向的地址。在obj的构造函数里,obj *po完成一系列的初始化工作。*/

00401A9C FF 15 D4 62 41 00         call        dword ptr [__imp__printf (004162d4)]

00401AA2 83 C4 08                         add         esp,8

00401AA5 3B F4                              cmp         esi,esp

00401AA7 E8 26 FD FF FF              call        _chkesp (004017d2)

    从以上分析我们可以看出,obj *po首先由operator new分配内存地址,然后以内存地址作为参数调用obj构造函数,也就是说在调用构造函数以前,对象的内存布局就已经完成.基本上我们的分析到这里就可以结束了.对于c++构造函数背后做的事我们也可以有一个比较清晰的认识了吧!

     

浅谈C++中的几种构造函数

3月中旬参加宣讲会,做了X软公司的C++笔试题,里面有一道“默认拷贝构造函数的题”,由于好久没复习C++基础知识,当时连基本的概念都想不来了了。于是乎,开始拿起以前看的谭浩强C++复习起来,现在书快要...
  • zxc024000
  • zxc024000
  • 2016年04月14日 17:56
  • 9181

算法改变世界——《算法之美——隐匿在数据结构背后的原理(C++版)》

所谓算法,就是隐匿在数据结构后背后的原理,在开发中好的算法可以降低时间复杂度提升可复用性。...
  • dongfeng9ge
  • dongfeng9ge
  • 2016年04月03日 16:33
  • 1167

C++中构造函数的作用

构造函数用于解决类中的对象初始化的问题 构造函数是一类特殊的函数,与其他的成员函数不同的是构造函数构造函数不需要用户来调用它,而是建立对象的时候自动的执行#include //#include "...
  • andrewgithub
  • andrewgithub
  • 2017年03月02日 15:30
  • 1910

C++各种构造函数的写法

构造函数 ,是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数...
  • baiyq369
  • baiyq369
  • 2017年02月08日 15:01
  • 1601

C++中class类 的 构造函数、析构函数

说明: demo.cpp:main.cpp所在之处 Line.h:线段类的.h文件 Line.cpp:线段类的.cpp文件 Coordinate.h:坐标类的.h文件 Coordinate.cpp:坐...
  • shangguanyunlan
  • shangguanyunlan
  • 2016年10月16日 17:05
  • 1743

C++构造函数—构造函数的声明与定义、带参数的构造函数

构造函数是一种随着对象创建而自动被调用的函数,它的主要用途是为对象作初始化。那么,构造函数到底是什么样子的呢? 构造函数的声明与定义 在C++中,规定与类同名的成员函数就是构造函数。需要注意的是,...
  • u011923747
  • u011923747
  • 2014年03月06日 17:32
  • 2108

C++之带有默认参数值的构造函数

在一个类中 ,如果程序员没有写,任何一个构造函数,则编译器将为该类提供一个默认的构造函数,如果程序员对类的构造函数进行了重载,则编译器将不提供默构造函数,这里需要手动书写一个无参的构造函数, 无参的...
  • u012129719
  • u012129719
  • 2015年07月23日 14:57
  • 6257

c++::让你足够了解构造函数和this指针

一、  this指针 【特性】 1、this指针的类型 类类型*const(类名*const),为右值 2、this指针并不是对象本身的一部分,不影响sizeof的结 果。 3、this的作...
  • lalu58
  • lalu58
  • 2016年10月17日 20:09
  • 3717

c++构造函数成员初始化中赋值和初始化列表两种方式的区别

先总结下: 由于类成员初始化总在构造函数执行之前 1)从必要性:      a. 成员是类或结构,且构造函数带参数:成员初始化时无法调用缺省(无参)构造函数      b. 成员是常量或引用:...
  • zizi7
  • zizi7
  • 2016年08月31日 11:26
  • 6178

C++构造函数初始化列表

先看两个例子: Demo
  • sszgg2006
  • sszgg2006
  • 2014年08月07日 19:36
  • 1348
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++构造函数的背后
举报原因:
原因补充:

(最多只允许输入30个字)