• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 从汇编看c++中默认构造函数的使用分析

从汇编看c++中默认构造函数的使用分析

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++默认构造函数,默认构造函数,不存在默认构造函数,类不存在默认构造函数,默认构造函数的作用等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

c++中的源程序:

int main() {
    X x;
}
</div>
上面的类X没有定义构造函数,仅仅有一个int i。

下面为其汇编程序:

    push    ebp;ebp为一个寄存器,总是指向一个函数调用堆栈的栈底,作为基址,用偏移量来访问该调用栈上的变量,但这里没有任何变量要访问,因此不起作用
    mov    ebp, esp;这两句的作用是为了保存调用main之前堆栈的基址ebp的值,并将ebp指向main调用栈的栈底
    push    ecx;将寄存器ecx的值压栈, 栈顶指针esp向前移动4byte
               ;这句的作用,为即将要创建的对象预留了4byte的空间,并向里面写入ecx的值

; 8    :     X x;
; 9    : }

    xor    eax, eax;eax也是一个寄存器,这里不起作用
    mov    esp, ebp;将栈顶指针移动到push ecx前的位置,即释放了4byte的空间
    pop    ebp;恢复基址到main调用之前的状态
    ret    0;函数返回
</div>
通过汇编发现,通过push ecx,编译器将堆栈栈顶移动4byte,并将寄存器的ecx的值写入,类X只含有一个int,大小刚好为4byte,因此这一句可以看成是为对象x分配空间。而接下来并没有任何函数的调用,来对这一块区域进行适当的初始化。所以,在没有明确定义一个构造函数的时候,不会有任何的初始化操作。

下面再看一段c++程序:

int main() {
    X x;
}
</div>
与上面相比,在类X里面增加了一个成员变量int j,类的大小变为8字节。

下面为对应汇编码:

    push    ebp
    mov    ebp, esp
    sub    esp, 8; 栈顶指针移动8byte,刚好等于类X的大小

; 9    :     X x;
; 10   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0
</div>
从汇编码看出,通过sub esp,8指令,堆栈确实留出了8byte的空间,刚好等于类X的大小,同样没有调用任何函数,来进行初始化操作。

所以,综上所述,在一个类没有明确定义构造函数的时候,编译器不会有任何的函数调用来进行初始化操作,仅仅是移动栈顶留出对象所需空间,也就是说,这种情况下,编译器根本不会提供默认的构造函数。

那么,书上说的由编译器提供默认的构造函数到底是怎么一回事呢?

下面看第一种情况,类里面有虚成员函数:

c++源码如下:


int main() {
    X x;
}
</div>
析构函数为虚函数

下面是main函数对应的汇编码:

    push    ebp
    mov    ebp, esp
    sub    esp, 12                    ; 为对象x预留12byte的空间,成员变量int i,int j占8byte,由于有虚函数,因此vptr指针占4byte

; 14   :     X x;

    lea    ecx, DWORD PTR _x$[ebp];获取x对象的首地址,存入ecx寄存器
    call    ??0X@@QAE@XZ;这里调用x的构造函数

; 15   : }

    lea    ecx, DWORD PTR _x$[ebp];获取对象x的首地址
    call    ??1X@@UAE@XZ                ; 调用析构函数
    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0
</div>
可以看到,对象x的构造函数被调用了,编译器确实合成了默认的构造函数。

下面是构造函数的汇编码:

从上面可以看出,类里面含有虚函数时,在没有明确定义构造函数时,编译器确实会为我们提供一个默认的构造函数。因此当一个类继承自虚基类时,也满足上面的情形。

接下来是第二种情形,类Y继承自类X,X明确定义了一个默认的构造函数(并非编译器提供),而类Y不定义任何构造函数:

先来看看c++源码:
    in

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++ 构造函数中使用new时注意事项
  • 对C++默认构造函数的一点重要说明
  • C++中函数的默认参数详细解析
  • C++函数参数取默认值的深入详解
  • 从汇编看c++中默认构造函数的使用分析

相关文章

  • 2017-05-28C++短路求值(逻辑与、逻辑或)实例
  • 2017-05-28实例解析C++设计模式编程中简单工厂模式的采用
  • 2017-05-28c++11可变参数使用示例
  • 2017-05-28C++运算符重载规则详解
  • 2017-05-28VC运用OPENGL加载BMP纹理图的实现方法汇总
  • 2017-05-28C++动态内存分配(new/new[]和delete/delete[])详解
  • 2017-05-28VC下实现fopen支持中文的方法
  • 2017-05-28C++基于递归和非递归算法求二叉树镜像的方法
  • 2017-12-31数据结构 最小生成树
  • 2017-05-28C++中的delete不会将操作数置0

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Unix下C程序内存泄漏检测工具Valgrind的安装与使用详解
    • __stdcall 和 __cdecl 的区别浅析
    • 解析C++编程中的#include和条件编译
    • C++进程间共享数据实例
    • 内部排序之堆排序的实现详解
    • 用C语言判断一个二叉树是否为另一个的子结构
    • VC使用TerminateProcess结束进程实例
    • C语言 共用体(Union)详解及示例代码
    • 使用C++进行Cocos2d-x游戏开发入门过程中的要点解析
    • 解析C++中不能重载为友元函数的四个运算符

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有