【问题标题】:How can specify the base class from whom I derive in multiple inheritance?如何指定我在多重继承中派生的基类?
【发布时间】:2017-02-20 11:32:51
【问题描述】:

我的编程课程有一个作业要求我设计一个抽象,从该抽象派生两个类,并从这两个派生类派生另一个类。

这带来了致命的死亡钻石问题。这可以通过虚拟继承来解决,尽管我需要将我的前两个类的对象实例化为我的抽象类的指针。而这不能通过任何类型的虚拟继承来完成。因此,如果有一种方法可以指定多重继承类将从其派生的基类,那将是非常有用的。

例子:

#include <iostream>

using namespace std;

class Base {
    public:
        virtual void foo(){};
        virtual void bar(){};
};

class Der1 : public Base {  
    public:
        virtual void foo();

};

void Der1::foo()
{
    cout << "Der1::foo()" << endl;
}

class Der2 : public Base {
    public:
        virtual void bar();
};

void Der2::bar()
{
        cout << "Der2::bar()" << endl;
}

class Join : virtual Der1, virtual Der2 {

    private:
        int atribb;



};

int main()
{
        Base* obj = new Join();
        ((Der1 *)(obj))->foo();
}

编译器错误:

nueve.cpp:在函数“int main()”中:

nueve.cpp:43:30: 错误:‘Base’是‘Join’的模糊基数

Base* obj = new Join();

【问题讨论】:

  • 查找纯虚函数并认真考虑让 Base 拥有这些。
  • 当你说“这不能通过任何类型的虚拟继承来完成”。你的意思是?我最初读到它是说您的类不允许您为此分配使用虚拟继承,但也许您的意思是您实际上确实想使用虚拟继承但不能做您想做的事情?
  • " 要求我设计一个从中派生出两个类的抽象" - 但这不是你所做的,Base 不是抽象的。您应该使Base 的函数成为纯虚拟函数(添加=0)。我不确定在这种情况下您是否还需要虚拟继承。
  • “死亡之钻”通常是一种“我不懂多重继承”的丰富多彩的说法。

标签: c++ c++11 inheritance


【解决方案1】:

使用虚拟继承。

class Der1 : public virtual Base {  
    public:
        virtual void foo();

};



class Der2 : public virtual Base {
    public:
        virtual void bar();
};

如果从基类派生时声明了virtual,如下例所示,最派生的类对象只包含一个基类子对象,这有助于解决您的情况的歧义。

做一些代码修改后,你的最终可执行代码:

以下示例中的代码更改:

添加 vitual 关键字,同时派生子类。 在派生大多数派生类时删除了“虚拟”关键字。 修改 main 以正确调用成员函数。

#include <iostream>

using namespace std;

class Base {
    public:
        virtual void foo(){};
        virtual void bar(){};
};

class Der1 : public virtual Base {  
    public:
        virtual void foo();

};

void Der1::foo()
{
    cout << "Der1::foo()" << endl;
}

class Der2 : public virtual Base {
    public:
        virtual void bar();
};

void Der2::bar()
{
        cout << "Der2::bar()" << endl;
}

class Join : public Der1, public Der2 {

    private:
        int atribb;



};

int main()
{
        Base* obj = new Join();
        obj->foo();
}

【讨论】:

    【解决方案2】:

    不清楚您要的是什么,尽管您似乎在说从Base 虚拟继承不合适。因此,假设这是正确的,您可以将Base* obj = new Join(); 替换为Base* obj = (Der1*)new Join();,您将获得指向Base 对象的指针,该对象是Der1 的基础。同样,您可以将其替换为Base* obj = (Der2*)new Join();,您将获得指向Base 对象的指针,该对象是Der2 的基础。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多