之前在上C++的课的时候,印象中有那么一句话:
如果一个类没有任何构造函数,那么编译器会生成一个默认的构造函数

今天在看《深度探索C++对象模型》的第二章:“构造函数语意学”的时候发现之前听到的说法是错误的。

比如说如下代码:

class A {
public:
int a;
};

int main(void) {
A a;
a.a = 4;
A a2;
a2.a=5;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
按照之前的说法,类A没有任何构造函数,编译器会自动生成一个默认的构造函数,但事实是并不会。把上面的代码反汇编后可以看到结果:

main:
push rbp
mov rbp, rsp #int main(void)
mov DWORD PTR [rbp-4], 4 #a.a = 4;
mov DWORD PTR [rbp-8], 5 #a2.a=5;
mov eax, 0 #return 0;
pop rbp
ret
1
2
3
4
5
6
7
8
我们可以发现这个类的对象被直接拿来用了,没有调用任何构造函数,也没有任何的初始化。

根据《深度探索C++对象模型》书上的说法,编译器只在一定需要默认构造函数时,才会创建默认构造函数,比如说:

class A {
public:
A() {a = 0; }
int a;
};
class B : public A {
A _tmp;
};
int main(void) {
B b;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
在类B对象初始化时,类B对象中存在一个需要默认构造函数进行初始化的类A对象,那么类B对象必须要有默认构造函数,因此编译器在迫不得已的情况下创建了类B对象的默认构造函数。
反汇编可以看到类B的默认构造函数:

A::A() [base object constructor]:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], 0
nop
pop rbp
ret
B::B() [base object constructor]:
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov rdi, rax
call A::A() [base object constructor]
mov rax, QWORD PTR [rbp-8]
add rax, 4
mov rdi, rax
call A::A() [complete object constructor]
nop
leave
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
lea rax, [rbp-8]
mov rdi, rax
call B::B() [complete object constructor]
mov eax, 0
leave
ret

————————————————
版权声明:本文为CSDN博主「zhangpeterx」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhangpeterx/article/details/102762410

最新文章

  1. oracle与mysql创建表时的区别
  2. SQLServer2008-镜像数据库实施手册(双机)SQL-Server2014同样适用
  3. O2O迈进智能时代 百度构建“服务生态”
  4. Android的post()方法究竟运行在哪个线程中
  5. iOS中的小知识点
  6. C Primer Plus(第五版)10
  7. Vim一些实用的用法
  8. Codeforces Round #332 (Div. 二) B. Spongebob and Joke
  9. mysql均衡负载
  10. 完整的struts.xml文件骨架
  11. java中final小结
  12. HTML5学习笔记<二>:元素,属性,格式化
  13. W10上面DOSBOX安装
  14. [转]html转码表
  15. dedecms利用memberlist标签调用自定义会员模型的会员信息
  16. PHP Zip File 函数
  17. Spring Web工程web.xml零配置即使用Java Config + Annotation
  18. 异步设备IO OVERLAPPED结构(设备内核对象 事件内核对象 可提醒IO)
  19. typescript静态属性,静态方法,抽象类,多态
  20. C#, CLR, and .NET Framework versions

热门文章

  1. Linux下的零拷贝
  2. MyBatis试题
  3. Shell 变量自增实现方法
  4. 【Beta阶段】第八次Scrum Meeting
  5. arthas安装进docker
  6. 11 JavaScript Utility Libraries you Should Know in 2019
  7. sensor【学习笔记】
  8. 大数据 Hibernate
  9. pycharm把制表符(tab)转换为空格(PEP8)
  10. (转)Navicat_12安装与破解,亲测可用!!!