首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++接口与继承

C++接口与继承
EN

Stack Overflow用户
提问于 2011-04-07 13:24:41
回答 4查看 1.3K关注 0票数 14

我想有一个接口IA和另一个扩展它IB。

然后A实现IA,B继承A,也实现IB。

但是,当编译B时出现错误,说明IA内容是未定义的,即使A定义了所有内容:(

代码语言:javascript
复制
class IA
{
public:
    virtual ~IA(){}
    virtual void foo()=0;
};
class IB : public IA
{
public:
    virtual void bar()=0;
};


class A : public IA
{
public:
    A();
    void foo();
};
class B : public A, public IB
{
public:
    B();
    void bar();
};

错误C2259:'B‘:无法实例化抽象类

由于下列成员:

'void::foo(Void)‘:是抽象的

EN

回答 4

Stack Overflow用户

发布于 2011-04-07 13:28:06

看一看C++常见问题,从以下几点开始:https://isocpp.org/wiki/faq/multiple-inheritance#mi-diamond

它详细解释了“可怕的钻石”和虚拟继承。

票数 17
EN

Stack Overflow用户

发布于 2011-04-07 13:27:35

(不,A没有定义任何东西。声明了A()void foo(),但没有定义它们。)

真正的问题是你的多重继承。

代码语言:javascript
复制
       B
     /   \
   A      IB
  /         \
IA          IA

如您所见,继承树中有两个IA“版本”,只有A实现了void IA::foo (不过,正如我前面提到的,这将给您一个链接器错误,因为您没有定义实现)。

void IB::IA::foo()仍未实现;因此,B本身“继承了抽象性”,您无法实例化它。

B也必须实现void foo(),或者您可以使用虚拟继承来攻击它。

票数 6
EN

Stack Overflow用户

发布于 2011-04-07 13:39:18

这是,对于虚拟继承而言,这是一个完全正确的案例,而这并不总是一种设计味道。

在并行层次结构接口/实现的情况下,表单“任意类->接口”的每个继承关系都应该标记为虚拟的:class A : public virtual IAclass B : public virtual IB, public Aclass IB : public virtual IA

这样,很可能(实现依赖但至少在概念上),在每个虚拟派生类中存储一个额外的指针,以知道它应该在哪里找到它的虚拟基。类ABIB将有指向IA的指针,而类B将有指向IB的指针。每个虚拟库也将有自己的vtable。

“可怕的钻石”的观点在图形上很好,但重点是派生类应该知道它们将使用的基类驻留在哪里,这就是虚拟继承的开始位置。显然,这里每个接口都需要一个vtable,而虚拟继承允许您这样做。

然后您可以继续并行,并添加额外的类CIC等等,只需记住:

--无论何时继承接口,实际上都要继承。

顺便说一下,COM类也有类似的设计。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5581806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档