空类大小
- 空类对象在内存中是有起始地址的,也就是说最少能存一个字节。所以一个空类的大小是1。
this指针调整
- 如果派生类继承自多个基类,那么派生类对象的开始地址和第一个基类子对象的开始地址是相同的。
- 调用派生类的成员函数的时候,会根据这个函数属于哪个基类,对this指针进行调整。
obj目标文件
概述
- 编译器会把每个源文件编程生成.obj或.o(目标文件),最后编译器会把这些目标文件链接成一个可执行文件。
- 在obj的信息里面查看一些信息。
方法
1 2 3 4 5 |
// 在Developer Command Prompt for VS 2019 dumpbin /all aet.obj // 输出 dumpbin /all aet.obj>aet.txt |
合成默认构造函数的情况
- 类A自己没有任何构造函数,但是它包含一个类B对象,这个类B有默认构造函数。
- 合成目的:为了合成的构造函数中调用类B的构造函数。
1 2 3 4 5 6 7 8 9 10 |
class A { public: void test() { std::cout << "hello" << std::endl; } public: int i; int j; std::string str; }; |
- 基类A有默认构造函数,派生类B没有任何构造函数。
- 合成目的:为了在合成的构造中调用基类的默认构造函数。
1 2 3 4 5 6 7 8 9 |
class A { public: A() {} }; class B : public A { public: int i; }; |
- 一个类有虚函数,同时该类没有任何构造函数。
- 合成目的:把类的虚函数表(vftable)的地址赋给类对象的虚函数表指针(vptr)
1 2 3 4 5 |
class A { public virtual func() { } }; |
- 棱形继承(虚继承)的情况下:
- 如果派生类C没有构造函数,编译器会为它合成默认构造函数
- 如果C的基类B1或B2没有构造函数,编译器也会为它合成默认构造函数
- 合成目的:
a.为B1或B2合成的目的,是因为需要在构造函数中把虚基类表(vbtable)的地址赋给B1或B2的虚基类表指针。
b.为C合成,因为需要在C的构造函数中根据B1和B2的虚基类表确定C的虚基类表,并且调用B1和B2的构造函数。
1 2 3 4 5 6 7 8 9 |
class A {}; class B1 : virtual public A {}; class B2 : virtual public A {}; class C : public B1, public B2 { public: }; |
合成拷贝构造函数
- 如果类A没有拷贝构造函数,但是类A含有一个类类型B的成员变量,且类B有自己的拷贝构造函数,这时,编译器会为类A合成出一个拷贝构造函数。
- 合成目的:在合成的拷贝构造函数里面调用类B的拷贝构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class A { public: A() {} A(const A&) {} }; class B { public: A a; }; int main() { B b; B b1 = b; return 0; } |
- 如果派生类B没有拷贝构造函数,但是它的基类A有拷贝构造函数。
- 合成目的:在合成的拷贝构造函数里面调用基类的拷贝构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class A { public: A() {} A(const A&) {} }; class B : public A { public: }; int main() { B b; B b1 = b; return 0; } |
- 如果类A没有拷贝构造函数,但是类A里面声明了虚函数或者继承了虚函数,当类A设计拷贝构造的行为时,编译器就会合成出一个拷贝构造函数出来。
- 合成目的:因为有虚函数,所有会生成一个虚函数表(vftable),而当用对象a去构造一个新对象a1时,需要让对象a1的虚函数表指针也指向A的虚函数表,这时,就需要在拷贝构造里面去做这个赋值行为。但是类A没有定义自己的拷贝构造,所以编译器会合成出一个拷贝构造出来并在里面做这个事情。
1 2 3 4 5 6 7 8 9 10 |
class A { public: virtual void test() {} }; int main() { A a; A a1 = a; return 0; } |
- 如果一个类没有拷贝构造函数,但是该类含有虚基类。
- 合成目的:当类C涉及拷贝构造行为时,需要在一个拷贝构造里面根据类B1和B2的虚基类表确定出类C的虚基类表,并且需要调用类B1和B2的拷贝构造函数。如果类C没有拷贝构造,编译器就会给它合成出一个出来来做这些事情。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class A {}; class B1 : virtual public A {}; class B2 : virtual public A {}; class C : public B1, public B2 { public: }; int main() { C c; C c1 = c; return 0; } |
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 打包_7z生成自解压打包exe07/11
- ♥ Soui九07/25
- ♥ C++标准模板库编程实战_关联容器12/07
- ♥ SOUI源码:log4z06/24
- ♥ C++17_第一篇12/20
- ♥ Pybind11记述:一07/04