The memory layout for C++ object

记录一下自己学习笔记

ATL Under the Hood - Part 1

http://www.codeproject.com/KB/atl/atl_underthehood_.aspx

告诉对象的类存模型,包括继承关系的类之间的内存模型

View Code
1 #include <iostream>
2  using namespace std;
3
4  class Base {
5  public:
6 Base() {}
7 virtual void f1() = 0;
8 virtual void f2() = 0;
9 int bi;
10 };
11
12  class Base2 {
13  public:
14 Base2() {}
15 virtual void f1() = 0;
16 virtual void f2() = 0;
17 int bi2;
18 };
19  class Drive : public Base {
20  public:
21 Drive() {}
22
23 int di;
24 };
25
26  class MostDrive : public Drive, public Base2 {
27  public:
28 MostDrive() {}
29 virtual void f1() { cout << "MostDrive::f1" << endl; }
30 virtual void f2() { cout << "MostDrive::f2" << endl; }
31 int ddi;
32 };
33
34  int main()
35 {
36 MostDrive d;
37
38 return 0;
39 }

对象对应得对象模型(在VC2005)

ATL Under the Hood - Part 2

http://www.codeproject.com/KB/atl/atl_underthehood_2.aspx

问题: 构造函数不能调用虚函数,为什么呢?

1.在构造函数里面会初始化虚表。

2.在继承链上,构造函数的调用是由继承链上的最顶层开始调用,最后一个调用创建对象本身的构造函数。

3.在每一层构造函数,会把自己的虚表重新覆盖直接基类的初始化的虚表。

4. 在每一个构造函数里,编译器会在调用用户代码之前,完成以上3步。

所以每一层的构造函数的虚表里面是自己重新写的函数,这是如果调用虚函数,查找虚表,找到的是自己重新定义的函数。

问题: C++ 中纯虚函数的原理。

语义上: 表示该类,不可以实例化,只能当做基类或者借口。比如有些基类,shape 实例化没有意义,就把它认为抽象类,用纯虚函数实现。

          尤其在COM里面,C++没有提供interface 关键字,纯虚函数用来模拟interface 关键字。

实现上: 为了调试方便,C++ 自定义一个函数,如果该函数是纯虚函数且没有实现,那么VC提供一个函数去替换该函数的地址。 如果当调用到该虚函数,就回报错。

     抽象类的析构函数可以是纯虚函数吗?

语义上:当然可以。

实现上:但是,其派生类的析构函数要调用基类的虚析构,在link的时候找不到基类的析构函数实现体,就报编译出错。

折中: 为基类的纯析构函数,提供实现体。

问题:#define ATL_NO_VTABLE __declspec(novtable)

__declspec(novtable) is Microsoft C++ specific extended attribute of class.

When it is used then compiler won't generate the code to initialize the vptr and vtable and reduce the generated code size.

Because in the inheritance chain, the class has pure function should not be instanced , but it can initialize the virtual table.

You can image that if the inheritance chain is much longer , it will it much time and space to initilze the object from the last node in the inheritance chain.

问题: Virutal inheritance

Requirement:

当有菱形继承时,控制基类的个数。

后面还有好几篇文章:

1. ATL Under the Hood Part 3 介绍函数模板,类模板, typename,特化, 以及用模板模拟多态。

2. ATL Under the Hood Part 4 介绍汇编

3. ATL Under the Hood Part 5 介绍ATL里面Thunk


原文地址:https://www.cnblogs.com/zhyg6516/p/1974423.html