仅具有1个虚拟继承的钻石问题 [英] Diamond problem with only 1 virtual inheritance

查看:105
本文介绍了仅具有1个虚拟继承的钻石问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这还能解决钻石问题吗?

Does this still solve the diamond problem?

class A
{};

class B : virtual A
{};

class C : A
{};

class D : B, C
{};

编辑:如果没有,那是什么?与此一样吗?

If not, what is it then? Is it the same as this?

class A
{};

class B : A
{};

class C : A
{};

class D : B, C
{};

还是其他东西?

推荐答案

钻石问题和对通用基本成员的模糊调用可以通过下面的等效图片来最好地描述,这些图片也可以使您深入了解内存模型

Diamond problem and ambiguous call to common base members can be best described through the following pictorial equivalent which also give an insight of the memory model

class A
{void foo(){};};

class B :public A
{};

class C :public  A
{};

class D :public  B,public  C
{};

由于继承只是简单地将两个对象的实现一个接一个地放置,因此基类A的所有方法在派生类B和C中都是重复的,其等效的图片表示形式为

Since Inheritance simply puts the implementation of two objects one after another, all methods of Base class A gets duplicated in derived class B and C, which has an equivalent pictorial representation as

                          A              A
                          |              |
                          |              |
                           B             C
                             \         /
                                \    /
                                  D

示例2

class A
{};

class B :public  virtual A
{};

class C :public  A
{};

class D :public  B,public  C
{};

使用virtual关键字,编译器为B类的vtable中的vptr(虚拟指针)生成派生类B的vtable,该vtable存储基类A的Offset.对于C而言,它仍复制基类A的所有方法因此,D类通过基类B通过vptr引用基类A的成员,而C类将基类A的成员引用为副本.因此,钻石问题和模糊性仍然存在.

With the virtual keyword, compiler generates a vtable for Derived class B with a vptr (virtual pointer) in the vtable of B which stores an Offset of the Base class A. For C, it still copies all method of base class A. So class D, via Base class B refers the members of base class A via a vptr where are Class C refers the members of base class A as a duplicate copy. So the diamond problem and ambiguity still persist.

                               A         A
                             /           |
                           /             |
                           B             C
                             \         /
                                \    /
                                  D

示例3

class A
{};

class B :public  virtual A
{};

class C :public  virtual A
{};

class D :public  B,public  C
{};

现在,当派生类B和C都虚拟继承A时,编译器将为B和C创建一个Vtable并在其每个vtable中创建一个vptr以引用基类A的偏移量.这最终解决了Diamond问题因为只能通过B或C看到一个副本

Now when both the derived classes B and C inherits A virtually, Compiler creates a Vtable for both B and C and creates a vptr in each of its vtable to refer the offset of the Base Class A. This finally solves the Diamond Problem as there is only one copy visible via B or C

                                  A                                          
                               /     \
                             /         \                                
                           B             C
                             \         /
                                \    /
                                  D

这篇关于仅具有1个虚拟继承的钻石问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆