C++:使用基类作为接口的实现。

问题描述 投票:28回答:5

在C++中,是否可以用另一个基类来提供派生类中的接口(即抽象基类)的实现?

class Base
{
    virtual void myfunction() {/*...*/};
}
class Interface
{
    virtual void myfunction() = 0;
}
class Derived
    : public Base, public Interface
{
    // myfunction is implemented by base
}

以上应该可以编译,但实际并不能实现。 有什么办法可以达到这种效果吗?

如果有人关心的话,想要这样做的原因是,在我的项目中使用来自另一个projectnamespace的通用库来提供接口的实现是有意义的(对于我的应用)。 我可以直接把所有的东西都包起来,但那似乎是很多额外的开销。

谢谢。

c++ inheritance
5个回答
12
投票

如果 Base 并非源于 Interface那你就得把电话转接到... ... Derived. 这只是 "开销 "的意思,因为你必须写额外的代码。 我怀疑优化器会让它和你原来的想法一样有效。

class Interface {
    public:
        virtual void myfunction() = 0;
};

class Base {
    public:
        virtual void myfunction() {/*...*/}
};

class Derived : public Interface, public Base {
    public:
        void myfunction() { Base::myfunction(); }  // forwarding call
};

int main() {
   Derived d;
   d.myfunction();
   return 0;
}

8
投票

试试这个。

class Interface
{
    virtual void myfunction() = 0;
}
class Base : public Interface
{
    virtual void myfunction() {/*...*/};
}
class Derived
    : public Base
{
    // myfunction is implemented by base
}

7
投票

不,(反正不是这样)

你可能会被其他语言(如Java、C#、ActionScript等)的处理方式所误导。

在C++中,多重继承和管理虚拟类的方式使得接口(其他语言中使用的接口)被淘汰。在这些其他语言中,接口是用来解决缺乏多重继承所发出的问题的(好或坏,这是一个选择)。

所以,如果你想做的只是提供一个通用的接口和一些提供默认实现的虚拟方法,只要在基类中实现即可。

class Interface
{
    virtual void myfunction() { /*...*/ } //default implementation
    virtual void yourFunction()  = 0 ; // this one HAVE TO be implemented by the user
};
class Derived
    : public Interface // don't need another class
{
    // myfunction is implemented by base
    void yourFunction(); // have to implement yourFunction
};
class DerivedB
    : public Interface // don't need another class
{
    void myFunction(); // myfunction is implemented by base but we implement it for this specific class
    void yourFunction(); // have to implement yourFunction
};

如果你想提供几个具有相同接口的基类,那么你的接口类就是其他类的基础。

// in this order
class Interface
{
    virtual void myfunction() = 0;
};
class BaseA : public Interface
{   
    // here "virtual" is optional as if the parent is virtual, the child is virtual too
    virtual void myfunction() {/*...*/}; // BaseA specific implementation
};
class BaseB : public Interface
{
    virtual void myfunction() {/*...*/}; // BaseB specific implementation
};

然而,有一种并不容易理解(读作:不建议)的方法来提供一个默认的实现,但强迫用户明确表示是否要使用它。它利用了这样一个事实,即即使是纯虚拟函数也可以有可以调用的默认实现。

class Interface
{
    virtual void myfunction() { /*...*/ } // default implementation
    virtual void yourFunction()  = 0 ; // this one HAVE TO be implemented by the user BUT provide a default implementation!
};

// in Interface.cpp 

void Interface::yourFunction() // default implementation of the virtual pure function
{ /*...*/ }

// in Derived.h

class DerivedA
    : public Interface // don't need another class
{
    // myfunction is implemented by base
    void yourFunction(); // have to implement yourFunction -- DerivedA specific
};

class DerivedB
    : public Interface // don't need another class
{
    void myFunction(); // myfunction is implemented by base but we implement it for this specific class
    void yourFunction() { Interface::yourFunction(); } // uses default implementation of yourFunction, hidden but existing
};

但不要这样做。


1
投票

Base 和 Interface 是完全不同的类型。编译器怎么会知道 "myfunction "是相关的?你必须在Derived中实现它,即使这个实现只是调用Base版本。


1
投票

这个回答是假设派生类想成为一个 CONCRETE 类或非抽象类,即希望能够实例化类型为 'Derived'.. 另外,我在回答中假设了公共成员函数。

不,派生类必须实现所有从基类继承的纯虚拟函数。在这种情况下,我们的派生类必须实现它从所有基类中继承的所有纯虚拟函数。'Base::myfunction' 虽由 'Derived' 不被视为对 'Derived::myfunction'

'Derived::myfunction' 仍然必须提供一个实现 'Interface::myfunction'.

一种可能是: 'Derived::myfunction' 可内部委托 'Base::myfunction'

然而,如果它不希望 Derived 是一个具体的类(我怀疑这是不是OP的意图),那么上述的类的安排是很好的(从语言的角度来看)。

© www.soinside.com 2019 - 2024. All rights reserved.