Let*_*_Be 5 c++ virtual-inheritance
我在过去5年的工作中假设虚拟继承打破了静态组合.
但是现在我发现,静态组合仍然保持不变,只有关于正确实例位置的附加信息.这是正确的吗?
Wol*_*ngP 21
class Point2d {
int x_, y_;
};
class Point3d : public Point2d {
int z_;
};
Run Code Online (Sandbox Code Playgroud)
+--------------+
| int x_ |
+--------------+
| int y_ |
+--------------+
Run Code Online (Sandbox Code Playgroud)
+--------------+ --+
| int x_ | |
+--------------+ +-- Point2d subobject
| int y_ | |
+--------------+ --+
| int z_ |
+--------------+
Run Code Online (Sandbox Code Playgroud)
Point3d静态地由Point2d和Point3d的成员组成.
在对象内部使用偏移量变量实现.
class Point3d : public virtual Point2d {
int z_;
};
Run Code Online (Sandbox Code Playgroud)
+-----------------+
| int z_ |
+-----------------+
| Point2d* _vbase | --> offset to Point2d subobject (2 in this case)
+-----------------+ --+
| int x_ | |
+-----------------+ +-- Point2d subobject
| int y_ | |
+-----------------+ --+
Run Code Online (Sandbox Code Playgroud)
Point3d* point3d->x_在此上下文中的访问将被转换为(C++ Pseudocode):
(static_cast<Point2d*>(point3d) + point3d->_vbase)->x_
Run Code Online (Sandbox Code Playgroud)
请注意,在vtable中有不同的方法来实现虚拟继承,例如偏移指针,这只是实现虚拟继承的一种方法.我选择了这个,因为通过vtables的间接需要更多的ascii绘图.
虚拟继承在这里没有任何好处,我希望(正如@Matthieu在评论中指出的)编译器优化这个类,以便它的内部数据布局与非虚拟继承中的相同.虚继承仅在多继承中有用(参见Vertex3d下面的类).
class Vertex : virtual Point2d {
Vertex* next_;
};
class Vertex3d : public Point3d, public Vertex {
};
Run Code Online (Sandbox Code Playgroud)
+-----------------+
| Vertex* next_ |
+-----------------+
| Point2d* _vbase | --> offset of Point2d subobject (2 in this case)
+-----------------+ --+
| int x_ | |
+-----------------+ +-- Point2d subobject
| int y_ | |
+-----------------+ --+
Run Code Online (Sandbox Code Playgroud)
+------------------+ --+
| int z_ | |
+------------------+ +-- Point3d subobject
| Point2d* _vbase1 | |--> offset to Point2d subobject (4 in this case)
+------------------+ --+
| Vertex* next_ | |
+------------------+ +-- Vertex subobject
| Point2d* _vbase2 | |--> offset to Point2d subobject (2 in this case)
+------------------+ --+
| int x_ | |
+------------------+ +-- shared Point2d subobject
| int y_ | | both Point3d and Vertex point to this
+------------------+ --+ single copy of Point2d
Run Code Online (Sandbox Code Playgroud)
在虚拟多重继承两个基类Vertex和Point3d共享基地Point2d在Vertex3d.非虚拟继承成员像往常一样布局.
虚拟多重继承的要点是所有后代Point3d和Vertex将共享一个副本Point2d.如果没有虚拟多重继承(="普通"多重继承),Point3d子对象和Vertex子对象都Vertex3d将拥有自己的副本Point2d:
Vertex3d没有虚拟多重继承的布局:+------------------+ --+
| int z_ | |
+------------------+ +-- Point3d subobject --+
| int x_ | | |
+------------------+ | +-- Point2d subobject
| int y_ | | | of Point3d
+------------------+ --+ --+
| Vertex* next_ | |
+------------------+ +-- Vertex subobject --+
| int x_ | | |
+------------------+ | +-- Point2d subobject
| int y_ | | | of Vertex
+------------------+ --+ --+
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
897 次 |
| 最近记录: |