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

时间:2010-09-10 16:00:40

标签: c++ inheritance

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

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

上面应该编译,但实际上并不起作用。有没有办法达到这个效果?

如果有人关心,想要这样做的原因是(对于我的应用程序)使用来自另一个项目/命名空间的通用库来提供项目中接口的实现是有意义的。我可以把所有内容都包起来,但这似乎是一些额外的开销。

感谢。

5 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:8)

试试这个:

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

答案 2 :(得分:6)

没有。 (不管怎么说)

您可能会误解其他语言(如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 public Interface // dont' need another clas
{
    // myfunction is implemented by base
    void yourFunction(); // have to implement yourFunction
}
class DerivedB
    : public public Interface // dont' need another clas
{
    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 public Interface // dont' need another clas
{
    // myfunction is implemented by base
    void yourFunction(); // have to implement yourFunction -- DerivedA specific
}

class DerivedB
    : public public Interface // dont' need another clas
{
    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
}

但不要这样做。

答案 3 :(得分:1)

响应是假设派生类想要成为CONCRETE类或非抽象类,即希望能够实例化'Derived'.类型的对象。我也在我的回复中假设公共成员函数。

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

'Derived::myfunction'仍需提供'Interface::myfunction'.

的实施

一种可能性是'Derived::myfunction'可以在内部委托给'Base::myfunction'

但是如果不希望Derived成为具体的类(我怀疑是OP的意图),那么上面的类安排就可以了(从语言的角度来看)

答案 4 :(得分:1)

Base和Interface是完全不同的类型。编译器应该如何知道“myfunction”是否相关?您必须在Derived中实现它,即使该实现仅调用Base版本。