0%

C++对象模型 Construction Destruction Copy

对象构造

  1. 递归从左到右调用virtual base class constructor
    • 存储virtual base object的offset
  2. 递归从左到右调用base class constructor(按照声明顺序,与initialization list顺序无关)
    • 如果在initialization list中有,传递参数
    • 如果base class是多重继承下的第二或之后的base class,调整this指针
  3. 设定virtual table pointer
  4. 按照member声明的顺序,如果initialization list中没有那么调用default constructor
  • 在copy operator时考虑自赋值的情况[[Chap.13 拷贝控制#拷贝赋值函数]]
  • 在虚基类的情况下,如果某个object是subject那么不会调用virtual base class的构造函数(棱形继承的情况下,虚继承的两个中间基类不会调用基类的构造函数),final class的构造函数会调用virtual base class的构造函数
  • 在构造函数中,调用virtual function,调用的应该是当前构造中的实例——所以vptr在base class constructor之后设定,但是在initilization list之前(避免有virtual function调用)

对象拷贝

  • 如果是菱形继承的情况,基类的拷贝可能会被多次调用

对象析构

  • 如果base class/member object没有析构函数,不需要析构函数
  1. destructor函数本体
  2. 调用member class objects的destructor(如果有)
  3. 重新设定vptr,将其指向base class的virtual table
  4. 调用base class destructor
  5. 调用virtual base class destructor

析构函数同构造函数,为了考虑虚继承的情况,可能会维护两份destructor实例

clang中,会有两份:

  • complete object destructor: 作为final class调用的destructor
  • base object destructor: 作为
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    D1::~D1() [complete object destructor]:                             # @D1::~D1() [complete object destructor]
    push rbp
    mov rbp, rsp
    sub rsp, 16
    mov qword ptr [rbp - 8], rdi
    mov rdi, qword ptr [rbp - 8]
    mov qword ptr [rbp - 16], rdi # 8-byte Spill
    lea rsi, [rip + VTT for D1]
    call D1::~D1() [base object destructor]
    mov rdi, qword ptr [rbp - 16] # 8-byte Reload
    add rdi, 12
    call B::~B() [base object destructor]
    add rsp, 16
    pop rbp
    ret
    D1::~D1() [base object destructor]: # @D1::~D1() [base object destructor]
    push rbp
    mov rbp, rsp
    sub rsp, 16
    mov qword ptr [rbp - 8], rdi
    mov qword ptr [rbp - 16], rsi
    mov rax, qword ptr [rbp - 8]
    mov rcx, qword ptr [rbp - 16]
    mov rcx, qword ptr [rcx]
    mov qword ptr [rax], rcx
    mov rdi, qword ptr [rip + std::cout@GOTPCREL]
    lea rsi, [rip + .L.str.1]
    call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@PLT
    jmp .LBB9_1
    .LBB9_1:
    add rsp, 16
    pop rbp
    ret
    mov rdi, rax
    call __clang_call_terminate

TODO

研究下构造函数