【问题标题】:C++ Using through an interface a class that inherits from several othersC++ 通过接口使用从其他几个继承的类
【发布时间】:2020-09-07 19:54:34
【问题描述】:

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

我想要一个从其他几个继承的类。另外,我想通过接口使用该派生类。所以我想,派生类应该扩展基类,派生接口应该扩展基接口。我会用其他语言做到这一点,但我认为 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;
                ^~~~

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

我做错了什么?谢谢。


编辑

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

【问题讨论】:

  • 你不能用pure virtual function创建一个类的对象
  • @d4rk4ng31 是的,我通过阅读编译器错误知道这一点。但如果可能的话,我不知道该怎么做。
  • @d4rk4ng31 是的,我知道,但是正如标题所说,我想通过接口使用派生类。
  • 你必须在Derived中实现blue()LIVE

标签: c++ inheritance interface multiple-inheritance


【解决方案1】:

这是 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;
}

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

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

【讨论】:

  • 一些关于虚拟继承的有趣读物:en.wikipedia.org/wiki/Virtual_inheritance
  • @JoanBotella,除了维基百科,几乎可以从任何地方学习...相信我,我是根据经验说话...
  • 我会建议像this这样的初学者
猜你喜欢
  • 2021-06-23
  • 1970-01-01
  • 2011-02-17
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 2010-10-07
  • 2014-11-26
  • 2022-01-25
相关资源
最近更新 更多