在下面的代码中,pC == pA:
class A
{
};
class B : public A
{
public:
int i;
};
class C : public B
{
public:
char c;
};
int main()
{
C* pC = new C;
A* pA = (A*)pC;
return 0;
}
但是当我在B中添加一个纯虚函数并在C中实现时,pA != pC:
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;
return 0;
}
在这种情况下,为什么 pA 不等于 pC?它们不是仍然指向内存中同一个“C”对象吗?
您会看到指针的值不同,因为新的虚拟函数导致将 vtable 指针注入到您的对象中。 VC++ 将 vtable 指针放在对象的开头(这是典型的,但纯粹是内部细节)。
让我们向 A 添加一个新字段,以便更容易解释。
class A {
public:
int a;
};
// other classes unchanged
现在,在记忆中,你的pA
and A
看起来像这样:
pA --> | a | 0x0000004
一旦你将 B 和 C 添加到混合物中,你最终会得到这样的结果:
pC --> | vtable | 0x0000000
pA --> | a | 0x0000004
| i | 0x0000008
| c | 0x000000C
如你看到的,pA
指向数据aftervtable,因为它不知道有关 vtable 的任何信息,也不知道如何使用它,甚至不知道它的存在。pC
确实知道vtable,所以它直接指向该表,这简化了它的使用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)