继承抽象基接口及其实现给 C2259

Posted

技术标签:

【中文标题】继承抽象基接口及其实现给 C2259【英文标题】:Inheriting both abstract base interface and its implementation gives C2259 【发布时间】:2017-02-23 11:20:02 【问题描述】:

我有以下情况:

具有许多纯虚函数的抽象基类:

interface IBase

    virtual void foo1() = 0;
    virtual void foo2() = 0;
    virtual void foo3() = 0;
    virtual void foo4() = 0;
    virtual void foo5() = 0;
    //  ...
    virtual void fooN() = 0;
;

继承它的两个小接口: 版本-A:

interface IBaseExt_A :
    public IBase

    virtual void foo_A() = 0;
;

版本-B:

interface IBaseExt_B :
    public IBase

    virtual void foo_B() = 0;
;

我创建了实现所有IBase 接口函数的基类:

class CBase :
    public IBase

public:
    virtual void foo1()  /* Do something... */
    virtual void foo2()  /* Do something... */
    virtual void foo3()  /* Do something... */
    virtual void foo4()  /* Do something... */
    virtual void foo5()  /* Do something... */
    //  ...
    virtual void fooN()  /* Do something... */
;

现在,我想用最少的代码来实现这两个派生版本。 我希望做类似的事情:

class CBaseExt_A :
    public IBaseExt_A,
    public CBase

public:
    virtual void foo_A()  /* Do something... */
;

显然这会产生错误:C2259: 'CBaseExt_A': cannot instantiate abstract class...这些错误涉及所有IBase 接口函数。

我知道我可以通过将所有 IBase 函数委托给 CBase 实现来解决这个问题:

class CBaseExt_A :
    public IBaseExt_A,
    public CBase

//  IBase implementation:
public:
    virtual void foo1()  CBase::foo1();
    virtual void foo2()  CBase::foo2();
    virtual void foo3()  CBase::foo3();
    virtual void foo4()  CBase::foo4();
    virtual void foo5()  CBase::foo5();
    //  ...
    virtual void fooN()  CBase::fooN();

//  IBaseExt_A implementation:
public:
    virtual void foo_A()  /* At last - do what we came here for...*
;

但这让我的小班CBaseExt_A变得庞大而复杂。有没有办法避免所有这些手动委托编码?

非常感谢,PazO

【问题讨论】:

虚拟继承可能会有所帮助。 C++ 中的接口关键字?你用的是什么编译器? @KirillKobelev - 我添加了:#define interface struct 【参考方案1】:

您应该使用以下代码:

interface IBase

    virtual void foo() = 0;
    ......
;

class CBase : virtual public IBase

    void foo()  
    ......
;

interface IBaseExt_A : virtual public IBase

    virtual void foo_A() = 0;
;

struct CBaseExt_A : public IBaseExt_A, public CBase

    virtual void foo_A()  /* Do something... */ 
;

请注意,IBase 类被继承的两个地方都应标记为虚拟。

【讨论】:

【参考方案2】:

我认为你应该指定两个继承之一是虚拟的。

那是钻石继承的地方

IBase 是顶层

IBaseExt_A 和 CBase 是中间层

CBaseExt_A 是底层

所以在 CBaseExt_A 中你想指定从哪个路径实现顶层,我想说你可能想在 IBaseExt_A 中指定 CBase 继承为公共虚拟而不是公共。

class CBaseExt_A :
public IBaseExt_A,
public virtual CBase

public:
    virtual void foo_A()  /* Do something... */
;

【讨论】:

发现需要在所有继承'IBase'的地方加上'virtual'关键字...

以上是关于继承抽象基接口及其实现给 C2259的主要内容,如果未能解决你的问题,请参考以下文章

十接口(接口的概念,实现,继承,实现)抽象类与抽象方法(抽象类,抽象方法概念,使用)

接口抽象类

设计模式-Template(行为模式) 采用 继承的方式 将算法封装在抽象基类中,在子类中实现细节。利用面向对象中的多态实现算法实现细节和高层接口的松耦合。

java中接口可以实现多个接口吗?

接口和抽象类

python中的抽象基类及相关用途