C++ 通过接口使用一个 class 继承自其他几个接口

C++ Using through an interface a class that inherits from several others

我正在学习 C++,我对多重继承和接口感到困惑 classes。

我想要一个 class 继承自其他几个。另外,我想通过接口使用派生的 class 。所以我想,派生 class 应该扩展基础 classes,而派生接口应该扩展基础接口。我会用其他语言做到这一点,但我认为 C++ 不能那样工作。

这是我认为应该有效的代码:

#include <iostream>

using std::cout;
using std::endl;

class
    Base1Itf
{
    public:
        virtual void blue() = 0;
};

class
    Base1Abs
:
    public Base1Itf
{
    public:
        void blue()
        {
            cout << "blue" << endl;
        }
};

class
    DerivedItf
:
    public Base1Itf
{
    public:
        virtual void red() = 0;
};

class
    Derived
:
    public Base1Abs,
    public DerivedItf
{
    public:
        void red()
        {
            cout << "red" << endl;
        }
};

int main()
{
    DerivedItf* d = new Derived();
    d->red();
    d->blue();
    delete d;
    return 0;
}

这是我得到的编译器错误:

src/test.cpp: In function ‘int main()’:
src/test.cpp:49:30: error: invalid new-expression of abstract class type ‘Derived’
  DerivedItf* d = new Derived();
                              ^
src/test.cpp:35:2: note:   because the following virtual functions are pure within ‘Derived’:
  Derived
  ^~~~~~~
src/test.cpp:10:16: note:       virtual void Base1Itf::blue()
   virtual void blue() = 0;
                ^~~~

示例中只实现了一个基础 class,但还会有更多。

我做错了什么?谢谢。


编辑

如果我删除 Base1Itf 的 Base1Abs 继承以避免钻石问题,编译器会显示相同的错误。

这就是众所周知的C++菱形问题。这就是你解决它的方法:

#include <iostream>

using std::cout;
using std::endl;

class Base1Itf {
public:
    virtual void blue() = 0;
    virtual ~Base1Itf() { }
};

class Base1Abs : virtual public Base1Itf {
public:
    void blue() override {
        cout << "blue" << endl;
    }
    virtual ~Base1Abs() { }
};

class DerivedItf : virtual public Base1Itf {
public:
    virtual void red() = 0;
    virtual ~DerivedItf() { }
};

class Derived : public Base1Abs, public DerivedItf {
public:
    void red() override {
        cout << "red" << endl;
    }
    virtual ~Derived() { }
};

int main() {
    DerivedItf* d = new Derived();
    d->red();
    d->blue();
    delete d;
    return 0;
}

继承中也推荐使用虚析构函数

你看,这里发生的是 classes Base1AbsDerivedItf 都继承了 blue 的副本。现在,当您从这 2 个继承另一个 class Derived 时,那个 class 继承了 blue 的 2 个副本,然后编译器开始想知道要调用哪个副本。因此,您实际上继承了 2 classes,结果只有 blue 的一个副本被继承