简体   繁体   English

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

[英]C++: using a base class as the implementation of an interface

In C++ is it possible to use another base class to provide the implementation of an interface (ie abstract base class) in a derived class?在 C++ 中是否可以使用另一个基类来提供派生类中的接口(即抽象基类)的实现?

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

The above should compile, but doesn't actually work.以上应该可以编译,但实际上不起作用。 Is there any way to achieve this effect?有什么办法可以达到这个效果吗?

In case anyone cares, the reason for wanting this is that it make sense (for my application) to use a generic library from another project/namespace to provide the implementation of an interface in my project.万一有人关心,想要这个的原因是(对于我的应用程序)使用来自另一个项目/命名空间的通用库来提供我项目中接口的实现是有意义的。 I could just wrap everything, but that seems like a lot of extra overhead.我可以把所有东西都包起来,但这似乎有很多额外的开销。

Thanks.谢谢。

If Base isn't derived from Interface , then you'll have to have forwarding calls in Derived .如果Base不是从Interface派生的,那么您必须在Derived转发调用。 It's only "overhead" in the sense that you have to write extra code.从您必须编写额外代码的意义上说,这只是“开销”。 I suspect the optimizer will make it as efficient as if your original idea had worked.我怀疑优化器会使它像您最初的想法一样有效。

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;
}

Try this:试试这个:

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

No. (not that way anyway)不。(反正不是那样)

You might be mislead by the way things are done in other languages like Java, C#, ActionScript, etc.您可能会被其他语言(如 Java、C#、ActionScript 等)的处理方式所误导。

In C++, multiple inheritance and the way virtual classes are managed makes interfaces (as used in other languages) obsolete.在 C++ 中,多重继承和虚拟类的管理方式使得接口(如在其他语言中使用的那样)过时了。 In those other languages, interfaces are used to fix problems issued from the lack of multiple inheritance (good or bad, it's a choice).在那些其他语言中,接口用于解决由于缺乏多重继承而引起的问题(好或坏,这是一个选择)。

So if what you want to do is just provide a general interface with some virtual methods providing default implementations, just implement in the base class :因此,如果您想要做的只是提供一个通用接口,其中包含一些提供默认实现的虚拟方法,只需在基类中实现:

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
};

If however, you want to provide several base classes that have the same interfaces, then think that your interface class is the bases of the other classes但是,如果您想提供多个具有相同接口的基类,则认为您的接口类是其他类的基类

// 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
};

There is however a not-really-easy-to-read (read: not recommanded) way to provide a default implementation BUT forcing the user to explicitely say if he want to use it or not.然而,有一种不太容易阅读(阅读:不推荐)的方式来提供默认实现,但迫使用户明确说明他是否想使用它。 It exploit the fact that even pure virtual functions can have default implementations that can be called :它利用了一个事实,即即使是纯虚函数也可以具有可以调用的默认实现:

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
};

But don't do it.但不要这样做。

The response is assuming that the derived class wants to be a CONCRETE class or a non abstract class, ie it is desired to be able to instantiate objects of type 'Derived'.响应假设派生类想要成为CONCRETE类或非抽象类,即希望能够实例化'Derived'.类型'Derived'.对象'Derived'. . . Also I assume public member functions in my response.此外,我在回复中假设公共成员功能。

No. The derived class has to implement all the pure virtual functions which it inherits from all the base classes.不可以。派生类必须实现它从所有基类继承的所有纯虚函数。 In this case 'Base::myfunction' though inherited by 'Derived' is not treated as an implementation of 'Derived::myfunction'在这种情况下,虽然由'Derived'继承的'Base::myfunction'不被视为'Derived::myfunction'

'Derived::myfunction' still has to provide an implementation of 'Interface::myfunction'. 'Derived::myfunction'仍然必须提供一个'Interface::myfunction'.

One possibility may be that 'Derived::myfunction' can internally delegate to 'Base::myfunction'一种可能性可能是'Derived::myfunction'可以在内部委托给'Base::myfunction'

However if it not desired for Derived to be a concrete class (which I doubt is the intent of OP), then the above arrangement of classes is fine (from language perspective)但是,如果不希望Derived成为一个具体的类(我怀疑这是 OP 的意图),那么上面的类安排就可以了(从语言的角度来看)

Base and Interface are totally different types. Base 和 Interface 是完全不同的类型。 How is the compiler supposed to know that "myfunction" is related?编译器应该如何知道“myfunction”是相关的? You must implement it in Derived, even if that implementation merely calls the Base version.您必须在 Derived 中实现它,即使该实现仅调用 Base 版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM