对象构造
- 递归从左到右调用 virtual base class constructor
- 存储 virtual base object 的 offset
- 递归从左到右调用 base class constructor (按照声明顺序,与 initialization list 顺序无关)
- 如果在 initialization list 中有,传递参数
- 如果 base class 是多重继承下的第二或之后的 base class,调整 this 指针
- 设定 virtual table pointer
- 按照 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 没有析构函数,不需要析构函数
- destructor 函数本体
- 调用 member class objects 的 destructor(如果有)
- 重新设定 vptr,将其指向 base class 的 virtual table
- 调用 base class destructor
- 调用 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
35D1::~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
研究下构造函数