Tam*_*lei 6 c++ gcc visual-c++
这是对此问题的后续问题.
考虑这个例子:
#include <iostream>
class A
{
};
class B : public A
{
public:
int i;
virtual void Func() = 0;
};
class C : public B
{
public:
char c;
void Func() {}
};
int main()
{
C* pC = new C;
A* pA = (A*)pC;
std::cout << "pC == " << std::hex << pC << "\n";
std::cout << "pA == " << std::hex << pA << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用Visual Studio 2010,输出(在我的机器上):
pC == 002DEF90 pA == 002DEF94
(这可以通过问题的接受答案来解释).
使用g ++,输出是:
pC == 0x96c8008 pA == 0x96c8008
所以,问题是,g ++的实现如何处理这种情况?C应该有vtable 的地址是什么?(我知道这是一个实现细节,不要说:)我对这个实现细节感兴趣出于好奇心).
经过多次摆弄,我终于想起了一些东西.
在空基类优化.
一旦A获得成员,结果就会改变.但是,只要它没有,编译器就不需要生成真实的布局A,重要的是保证每个A"对象"将具有与任何其他A对象不同的地址.
因此,编译器只使用B子对象的地址(继承自A)作为合适的地址.事实证明,B并且C具有相同的地址(第一个基地+都有虚拟方法).
另一方面,如果A有一个成员或如果第一个成员B是a A(还有其他条件),那么EBO不能再适用,你会注意到地址的跳跃.