【问题标题】:Diamond inheritance, c++ handling [duplicate]钻石继承,C++处理[重复]
【发布时间】:2016-09-21 20:12:57
【问题描述】:

因此我们有经典的钻石问题和 int 的解决方案:

class A
{
public:
    A()
    {
        std::cout << "A c'tor" << std::endl;
    }
    void f()
    {
        std::cout << "A::f()" << std::endl;
    }
};

class B :virtual public A{};

class C :virtual public A{};

class D : public B, public C{};

编译器是如何处理这个问题的,所以它只创建了一个 A 的实例? 请尽可能具体地回答。

【问题讨论】:

标签: c++ inheritance multiple-inheritance virtual-inheritance diamond-problem


【解决方案1】:

标准没有指定如何编译器应该处理它,但通常(AFAIK gccMSVC),它是按照我在下面描述的方式实现的。

当类继承正常时,它将包含所有基类成员

当类虚拟继承时,它将(而不是整个类)包含指向该基类所在位置的指针,虚拟基类应位于大多数派生对象中:

struct A
{
   int i;
};

struct B: virtual A{};

struct C: B{};



int someFunction()
{
    /* b internally contains pointer that points to it's (virtual)base class , 
    in this case B itself is most derived object so it points to base class
    which is stored somewhere inside B */

    B b;


    /* now subobject B (which is stored inside C) contains pointer that
      ,again points to it's (virtual) base class 
      ,but that class now resides in most derived object which is C */

    C c;
}

加分:

你能找出错误在哪里吗?

struct A
{
    std::string message;

    A(std::string parameter): message(parameter) {}

};

struct B: virtual A
{
    B(std::string parameter): A(parameter) {}
};

struct C: B
{
    C(){}
};

【讨论】:

  • "它将(而不是整个类)包含指针"。这是一个实现细节。并非所有编译器都使用内部指针。
  • @curiousguy 是的,你是对的,标准只指定会发生什么,而不是应该如何发生。我试图简短地回答。我在答案中添加了一些行。
  • 确定内部指针实现是“常见的”,或者最常见的,我知道这是 MSVC 所做的,所以编译器打算生成兼容的代码(在二进制级别)必须遵循这个方案,大多数 Windows 编译器可能会这样做。但是它会浪费对象中的一些空间。
  • @curiousguy 我已经用gcc 对其进行了测试,它似乎也使用了内部指针,更具体地说是virtual pointer 指向virtual table。它在对象中占据了一些位置,但它并没有那么糟糕,因为相同的(虚拟)指针用于解析虚拟函数。
  • 我不称这​​些“内部指针”而是“vptr”(或 vtable 指针)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-23
  • 2013-05-16
  • 2019-10-09
  • 2014-06-15
相关资源
最近更新 更多