很奇怪不是么?很多人在使用C++。但很少有人真正关心C++ Compile是如何实现的。
Jan Gray在1994曾经写了一篇叫做C++ under the Hood的文章,介绍了Visual C++的实现细节。这篇指南就是基于Jan的文章之上,我同时会将Jan文章中让人难于理解的地方详细阐述。希望这篇指南可以让更多的人了解C++的底层实现机制。
The layout of a Class
struct B {
public:
int bm1;
protected:
int bm2;
private:
int bm3;
};
Struct B 在内存中的layout是怎么样的? Visual C++保证B中的member variables 在内存中的layout与它们生命的顺序一致。Struct B在内存的中layout应该是这个样子的:
Single Inheritance
struct C {
int c1;
void cf();
};
struct D : C {
int d1;
void df();
};
在Visual C++中保证在C的member variables 在内存中的位置永远在D的起始位置。就像这样:
这样做的好处是当C* pC = new D();Visual C++不需要为pC做额外的displacement 转换。pC 的address equal D* pD = new D();中的pD.
Multiple Inheritance
比较复杂:
struct E {
int e1;
void ef();
};
struct F : C, E {
int f1;
void ff();
};
多重继承比较复杂,他们的Base和Derived的指针的位置不再相同。
F f;
// (void*)&f == (void*)(C*)&f;
// (void*)&f < (void*)(E*)&f;
通过如下的Diagram of layout你可以看得更加清楚:
为什么在图中C在E的上面?这是Visual C++ 的convention罢了,基类在内存中的layout correspond to 他们的的声明顺序。因为C的声明在E的前面,所以我们看到的F在内存的layout就是这样子的。
由此图可知,E *pE = new F() 与C *pC = new F()中的pE 和pC指向的内存位置并不相同