【问题标题】:Inheritance with interfaces接口继承
【发布时间】:2021-04-10 01:50:39
【问题描述】:

我目前正在尝试围绕 C++ 继承的基础知识。考虑以下代码:

// Interfaces

class InterfaceBase
{
public:
    virtual void SomeMethod() = 0;
};

class InterfaceInherited : public InterfaceBase
{
};

// Classes

class ClassBase : public InterfaceBase
{
public:
    virtual void SomeMethod()
    {
    }
};

class ClassInherited : public ClassBase, public InterfaceInherited
{
};

int main()
{
    ClassBase myBase; // OK
    ClassInherited myInherited; // Error on this line

  return 0;
}

这里我有两个具有继承关系的接口。实现接口的两个类也是如此。

这给了我以下编译器错误:

C2259 'ClassInherited': cannot instantiate abstract class

似乎ClassInherited类没有从ClassBase继承SomeMethod的实现。因此它是抽象的,不能被实例化。

为了让 ClassInheritedClassBase 继承所有已实现的方法,我需要如何修改这个简单的示例?

【问题讨论】:

  • 在这种情况下,无需再次InterfaceInherited继承ClassInherit。它已经从 ClassBase 继承了该接口。
  • 事实上它继承自ClassBaseInterfaceInherited,但是最后一个没有定义SomeMethod的实现,所以一个还在ClassInherited中挂起;这使得ClassInherited 抽象,所以不是固定不变的。

标签: c++ inheritance interface


【解决方案1】:

您遇到的是diamond problem。 解决方案是使用virtual inheritance (Live),确保只有一个基类成员的副本被孙子继承:

// Interfaces
class InterfaceBase
{
public:
    virtual void SomeMethod() = 0;
};

class InterfaceInherited : virtual public InterfaceBase
{
};

// Classes
class ClassBase : virtual public  InterfaceBase
{
public:
    virtual void SomeMethod()
    {
    }
};

class ClassInherited : public ClassBase, public InterfaceInherited
{
};

int main()
{
    ClassBase myBase; // OK
    ClassInherited myInherited; // OK
    return 0;
}

【讨论】:

  • 如果你也清理一下就好了。增加缩进并删除一些行。没有理由这需要滚动。请参阅我对 OP:s 帖子的编辑。
  • 一些编译器会warn你关于这个继承结构。这些警告可以是ignored or silenced
猜你喜欢
  • 1970-01-01
  • 2010-09-21
  • 2015-10-12
  • 2011-03-24
  • 1970-01-01
相关资源
最近更新 更多