虚拟多重继承和指针
Virtual multiple inheritance and pointers
给定以下类层次:
class A {
int x;
public:
A(int X) : x(X) {}
void setX(int x) { this->x = x; }
};
class B : public virtual A {
int y;
public:
B(int X, int Y) : A(X), y(Y) {}
};
class C : public virtual A {
int z;
public:
C(int X, int Z) : A(X), z(Z) {}
};
class D : public C, public B {
public:
D(int x, int y, int z) : A(x), C(x,z), B(x,y) {}
};
和下面的main:
int main (void)
{
D x(2,3,4);
A* temp1 = &x;
B* temp2 = &x;
C* temp3 = &x;
}
似乎temp1,temp2和temp3都指向不同的地址。B和C不应该共享同一个A对象吗?毕竟,每个C和B对象也是A,所以指针应该首先"看到"A对象。没有?另外,C指针包含了X的地址。这是一个D对象。为什么?
下面是内存映射:
&x 0x0036f828 {...} D *
temp1 0x0036f838 {x=5 } A *
temp2 0x0036f830 {y=3 } B *
temp3 0x0036f828 {z=4 } C *
这就是对象在内存中的表示方式。
所以你的对象是这样的
+ 0x0036f828
- D
- int z (C)
- int y (B)
- int x (A)
c++强制转换只给出对象开始的偏移量。
因此,您可以看到,偏移量只是类A,B,C(因为它们包含)的整数大小和类B,C的虚表大小。而D没有成员,所以它的偏移量为0。
请注意,c++编译器按照实际编写成员和基类的顺序设置内存布局。
所以如果你改变D中基类的顺序,那么你会得到不同的结果:
class D : public B, public C
现在B将是d之后的第一个类。
你说得对,B和C需要共享同一个A对象。这正是这里将要发生的事情。您看到的地址实际上是每个类唯一的虚拟表的地址。在虚继承的情况下,每个类的虚表都有一个指向虚基类的指针,在本例中为对象a。
所以B类和C类的虚表都有一个指针,每个指针都指向对象a的相同地址。
如果用普通结构体写出来,结果可能是这样的:
struct A {
int x;
};
struct B {
A *ap;
int y;
};
struct C {
A *ap;
int z;
};
struct D {
C c;
B b;
A a;
};
int main (void)
{
D x;
A* temp1 = &x.a;
B* temp2 = &x.b;
C* temp3 = &x.c;
}
由于B
和C
使用虚继承,它们只包含指向基类的指针,而不包含实际对象。您可以看到,由于c
位于D
的开头,它们将具有相同的地址。
相关文章:
- 关于C++中具有多重继承"this"指针的说明
- 带有此指针的模板类多重继承构造函数不起作用?
- 多重继承 c++ 和指针
- 指针到成员函数和多重继承
- C 多重继承和向上的智能指针破坏会导致VS 2017中的堆腐败
- 指针调整没有多重继承
- C 多重继承 - 编译器修改我的指针
- 多重继承指针比较
- 多重继承期间的对象构造和虚拟指针
- MinGW 4.7.0 到 4.7.2 错误:使用混合虚拟和非虚拟多重继承时成员函数中的"this"指针无效
- 指向多重继承中继承的数据成员的指针
- 从一个基类的指针对另一个基类的多重继承和泛型访问
- C++多重继承+虚拟函数(-歧义)=怪异行为(也是函数指针)
- 在C++多重继承的情况下如何获得正确的指针"alignment"?
- 多重继承和this指针
- 多重继承和指针实现
- 虚拟多重继承和指针
- 多重继承中的指针相等
- 在c++中获取一个类的指针,该类是另一个具有多重继承的类的一部分
- 比较指针.多重继承问题