• C++编译器会对没有构造函数的类生成默认构造函数吗?(有必要的时候才生成,要看情况。有反汇编验证)


    之前在上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

  • 相关阅读:
    c# 测试篇之Linq性能测试
    F# 笔记
    c# DataSource和BindingSource
    .net中配置的保存格式笔记
    泛型约束(转)
    c# 调用showDialog后需要Dispose
    c# 实现ComboBox自动模糊匹配
    c# 二进制或算法实现枚举的HasFlag函数
    C# WinForm自定义控件整理
    微软中文MSDN上的一些文章链接
  • 原文地址:https://www.cnblogs.com/findumars/p/11809686.html
Copyright © 2020-2023  润新知