对象构造
- 递归从左到右调用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
研究下构造函数