C++ C++;多重继承和vtables:使用成员变量访问而不是方法访问
这是对本链接中提出的问题和代码的修改: . 我从这个链接了解了如何设置vptr和vtable 我的问题是,bp->OutB()如何检索INTA的值,INTA是classA的成员。 我想我们把这个指针传递给这个方法,它查看类C的B部分。 明确地 C类的内存布局假定为32位C++ C++;多重继承和vtables:使用成员变量访问而不是方法访问,c++,compiler-construction,C++,Compiler Construction,这是对本链接中提出的问题和代码的修改: . 我从这个链接了解了如何设置vptr和vtable 我的问题是,bp->OutB()如何检索INTA的值,INTA是classA的成员。 我想我们把这个指针传递给这个方法,它查看类C的B部分。 明确地 C类的内存布局假定为32位 &obj. +0: vptr( pointer to virtual method table of classC( for classA). +4: value of a. +8: vptr( pointer to v
&obj.
+0: vptr( pointer to virtual method table of classC( for classA).
+4: value of a.
+8: vptr( pointer to virtual method table of classC( for classB).
+12: value of b.
+16: value of c.
我的问题是,当我们执行:bp->OutB()时,我们将&obj+8作为指向的指针传递,但在这种情况下,它如何最终检索类a的成员:int a
#include <iostream>
using namespace std;
class A
{
public:
virtual void OutA() = 0;
int a;
};
class B
{
public:
virtual void OutB() = 0;
int b;
};
class C : public A, public B
{
void OutA();
void OutB();
int c;
};
void C::OutA()
{
cout << "Out A " << endl;
}
void C::OutB()
{
cout << "Out B " << " a is: " << a << endl;
}
int main()
{
C obj;
obj.a = 10;
obj.b = 20;
obj.c = 30;
obj.OutA();
obj.OutB();
A* ap = (A*)&obj;
B* bp = (B*)&obj;
ap->OutA();
bp->OutB();
return 0;
}
#包括
使用名称空间std;
甲级
{
公众:
虚空OutA()=0;
INTA;
};
B类
{
公众:
虚空OutB()=0;
int b;
};
C类:公共A、公共B
{
void out();
void OutB();
INTC;
};
void C::OutA()
{
如果你希望它打印任何东西,那么a is:10
你显然误解了一些东西。C::OutB
的实现打印a
。你用来访问对象的指针是完全不相关的。我的观点是编译器调整指针的主要原因是让它看起来像有实例一样当我们这样做B*bp=(B*)时,类B的&基本上,它不是指向对象obj的原始地址,而是向它添加了偏移量,这样任何B类的方法都会感觉像是被传递给了B类实例的指针。但它仍然能够访问a,所以我怀疑编译器再次计算偏移量以获得int a。如果是这样,为什么它必须将c中的偏移量传递给cla本例中为ss B指针。C
同时包含A
和B
。在本例中A
和C
将共享相同的地址,并且B
将处于偏移位置(A的大小+可能的对齐)。编译器可以在所有这三个指针之间进行转换。我仍然不明白这与访问数据成员有什么关系,或者您对什么感到困惑。仍然会有一个偏移量,没有任何虚拟函数和vtable。@超级:我不确定您是否了解vpointer和vtable是如何在多重继承中组织的。我不明白这一点这意味着,无论vtable是如何组织的(就语言而言,甚至不必是vtable。这是一个实现细节),它都不会影响编译器解析a
地址的方式。