gpt4 book ai didi

c++ - 虚拟继承不会破坏静态组合?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:50:28 24 4
gpt4 key购买 nike

过去 5 年我一直在假设虚拟继承打破了静态组合。

但现在我发现,静态组合仍然存在,只是关于正确实例位置的附加信息。这样对吗?

最佳答案

非虚拟继承中的数据布局:

class Point2d {
int x_, y_;
};

class Point3d : public Point2d {
int z_;
};

点2d:

+--------------+
| int x_ |
+--------------+
| int y_ |
+--------------+

Point3d:

+--------------+   --+
| int x_ | |
+--------------+ +-- Point2d subobject
| int y_ | |
+--------------+ --+
| int z_ |
+--------------+

Point3d由Point2d和Point3d的成员静态组成。

虚继承下

通过对象内部的偏移量变量实现。

class Point3d : public virtual Point2d {
int z_;
};

Point3d:

+-----------------+
| int z_ |
+-----------------+
| Point2d* _vbase | --> offset to Point2d subobject (2 in this case)
+-----------------+ --+
| int x_ | |
+-----------------+ +-- Point2d subobject
| int y_ | |
+-----------------+ --+

在此上下文中访问 Point3d* point3d->x_ 将被转换为(C++ 伪代码):

(static_cast<Point2d*>(point3d) + point3d->_vbase)->x_

请注意,有不同的方式来实现虚拟继承,例如 vtable 内部的偏移指针,这只是实现虚拟继承的一种方式。我选择这个是因为通过 vtables 的间接访问需要更多的 ascii 绘图。

虚拟继承在这里没有任何好处,我希望(正如@Matthieu 在评论中指出的那样)编译器优化此类,使其内部数据布局与非虚拟继承相同。虚拟继承仅在多重继承中有益(参见下面的 Vertex3d 类)。

这在多重继承中看起来如何?

 class Vertex : virtual Point2d {
Vertex* next_;
};

class Vertex3d : public Point3d, public Vertex {
};

顶点:

+-----------------+
| Vertex* next_ |
+-----------------+
| Point2d* _vbase | --> offset of Point2d subobject (2 in this case)
+-----------------+ --+
| int x_ | |
+-----------------+ +-- Point2d subobject
| int y_ | |
+-----------------+ --+

顶点3d:

+------------------+   --+
| 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

在虚拟多重继承中,基类 VertexPoint3d 共享 Vertex3d 中的基类 Point2d。非虚拟继承成员照常布局。

虚拟多重继承的要点是 Point3dVertex 的所有后代将共享一份 Point2d。如果没有虚拟多重继承(=“普通”多重继承),Point3d 子对象和 Vertex3dVertex 子对象都将拥有自己的 拷贝code>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
+------------------+ --+ --+

引用资料:

  • Lippman:C++ 对象模型内部。第三章

关于c++ - 虚拟继承不会破坏静态组合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4335288/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com