`
rocky2com
  • 浏览: 38592 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

构造函数 做了什么事

 
阅读更多

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

本文适用于

Xp sp3

Vs2008

欢迎转载,但请保留作者信息

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

写一个简单的类:

classCParentA

{

public:

CParentA() {}

public:

intparenta_a;

intparenta_b;

public:

virtualvoidparenta_f1() {this->parenta_a = 0x10;}

virtualvoidparenta_f2() {this->parenta_a = 0x20;}

public:

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

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

};

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

CParentA() {}

00401330 55pushebp

00401331 8B ECmovebp,esp

00401333 51pushecx

00401334 89 4D FCmovdword ptr [ebp-4],ecx

00401337 8B 45 FCmoveax,dword ptr [this]

0040133AC7 00 60 68 40 00 movdword ptr [eax],offset CParentA::`vftable' (406860h)

00401340 8B 45 FCmoveax,dword ptr [this]

00401343 8B E5movesp,ebp

00401345 5Dpopebp

00401346 C3ret

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

00401337 8B 45 FCmoveax,dword ptr [this]

0040133AC7 00 60 68 40 00 movdword ptr [eax],offset CParentA::`vftable' (406860h)

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

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

CParentA pa;

0040111E 8D 4D F0leaecx,[pa]

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

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

CParentA::CParentA:

004013D0 55pushebp

004013D1 8B ECmovebp,esp

004013D3 51pushecx

004013D4 89 4D FCmovdword ptr [ebp-4],ecx

004013D7 8B 45 FCmoveax,dword ptr [this]

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

004013E0 8B 45 FCmoveax,dword ptr [this]

004013E3 8B E5movesp,ebp

004013E5 5Dpopebp

004013E6 C3ret

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

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

CParentA pa;

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

    分享到:
    评论

    相关推荐

      枚举类型与构造函数.doc

      本文档为自己手动书写样例,涉及到java项目中经常用到的枚举类型,使用枚举类型有利于快速引起区分对应字典键值对

      c++ 子类构造函数初始化及父类构造初始化的使用

      如果子类的构造函数没有显示地调用父类的构造函数,则默认调用父类的无参构造函数,至于什么事显式调用,在下面会详细说明!关于子类中构造函数的构造原则,总结如下,欢迎大家指导与批评。  1.父类没有声明构造...

      jQuery构造函数init参数分析续

      实现功能是和jq一样的, 只是jq的把构造函数放进原型;如果非要说原因,个人理解jq这样写整体结构清晰,先是入口构造函数,紧跟着是原型部分(原型里面init是初始化),但是不好理解;乍一看确实挺绕, 我也是看了好久才明白...

      泛型<编程>:转移构造函数

      我想你们知道得很清楚,创建,拷贝,并摧毁临时对象是你的C++编译器爱做的事,临时对象在内部被创建,不幸的是这极大影响到了C++程序的执行效率。实际上,临时对象是C++程序中最大的影响效率因素。这样的代码看上去...

      C++ 最通俗易懂的构造和析构函数讲解

      注意:对象的初始化和清理工作是编译器强制我们要做的事情,即使你不提供初始化操作和清理操作,编译器也会给你增加默认的操作,只是这个默认初始化操作不会做任何事。 构造函数:实例化对象的时候系统自动调用 析构...

      对于JS继承详细介绍( 原型链,构造函数,组合,原型式,寄生式,寄生组合,Class extends)

      说实在话,以前我只需要知道“寄生组合继承”是最好的,有个祖传代码...其中,原型链继承和原型式继承有一样的优缺点,构造函数继承与寄生式继承也相互对应。寄生组合继承基于Object.create, 同时优化了组合继承,成

      数据结构多项式相乘的源代码

      直接可以运行的源代码!方便大家参考。曾经自己苦苦在网上搜索无果。。。知道那是多么痛苦的事·

      c++中new和delete操作符用法

      当我们使用关键字new在堆上动态创建一个对象时,它实际上做了三件事:获得一块内存空间、调用构造函数、返回正确的指针。当然,如果我们创建的是简单类型的变量,第二步就会被省略。 new用法: 1. 开辟单变量地址空间...

      JavaScript思维导图

      JavaScript思维导图,详细介绍作用域,函数,构造函数,ES5,ES6,数组高阶函数。详细介绍全局,局部,块级,模块作用域是怎么回事‘详细解释”闭包“的概念是什么?使用场景?遇到的问题?怎么使用?详细介绍...

      高质量C++编程指南.zip

      9.6 示例:类STRING的拷贝构造函数与赋值函数 73 9.7 偷懒的办法处理拷贝构造函数与赋值函数 75 9.8 如何在派生类中实现类的基本函数 75 9.9 一些心得体会 77 第10章 类的继承与组合 78 10.1 继承 78 10.2 组合 80 ...

      javascript创建对象、对象继承的实用方式详解

      创建对象、对象继承实际上是一回事:我们所需要的实例对象通过构造函数获得私有属性、通过原型链获得共享的属性。什么是好的方式?私有属性通过构造函数的方式获得(不考虑实例中自定义私有属性)且不需要重写,共享...

      xml与反射.txt

      第三:通过clazz获得构造函数:Constructors cons=clazz.getDeclaraedConstructors(Class[]null);//调 用默认的构造函数 第四:然后通过构造函数构造对象:Car car=(Car)cons.newInstance();//获取类的默认构造函数...

      JS中new的原理及实现

      在调用new的过程中做了四件事: 1.新生成对象 2.链接到原型 3.绑定this 4.返回新对象 接下来就针对这几点,实现类似new的方法 //定义create方法 function create(){ //定义空对象 let obj = {}; //取出参数...

      彻底理解js面向对象之继承

      回顾:构造函数,原型,实例三者的关系 每一个构造函数都有一个原型对象(Person.prototype);原型对象都包含指向构造函数的指针(constructor);每个实例都包含指向原型对象的指针(看不见的_proto_指针) 原型链是怎么...

      玩转JavaScript OOP – 类的实现详解

      但是JavaScript的函数功能非常灵活,其中之一就是构造函数,结合构造函数和原型对象可以实现”类”。 对象和类的概念 对象 “对象”是面向对象编程中非常重要的一个概念,一个对象是一个“东西”(某个人或某件事)...

      HTML5新特性 多线程(Worker SharedWorker)

      There is no doubt that JavaScript是没有多线程之说的,他只能一件事一件事的做,做完一件事再做下一件事,假如你的js要花一段比较长的时间做一件事的话,那么浏览器将会卡顿一段时间,不对用户的操作产生响应,这...

      JavaScript寄生组合式继承实例详解

      //通过执行构造函数设置属性 function A(){ this.a = 1; } //通过原型设置属性 A.prototype.b = 1; 所以: 一个类Sub要继承另一个类Super,需要继承父类的prototype下的属性,还要执行一下父类的构造函数。 即一个...

      HDUc++上机测试真题(错题汇集1

      2、new做两件事,一是分配内存,二是调用类的构造函数 3、new建立的是一个对象,而malloc分配的是一块内存 4、new/delete是保留字,不需要头文

    Global site tag (gtag.js) - Google Analytics