如何在C ++中使用非虚拟接口方法实现接口类? [英] How to implement an interface class using the non-virtual interface idiom in C++?

查看:395
本文介绍了如何在C ++中使用非虚拟接口方法实现接口类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中,一个接口可以通过一个类实现,所有的方法都是纯虚函数。

In C++ an interface can be implemented by a class with all its methods pure virtual.

这样的类可以是库的一部分,用于描述对象应该实现哪些方法,以便能够与库中的其他类一起使用:

Such a class could be part of a library to describe what methods an object should implement to be able to work with other classes in the library:

class Lib::IFoo
{
    public:
        virtual void method() = 0;
};

class Lib::Bar
{
    public:
        void stuff( Lib::IFoo & );
};



现在我想使用Lib :: Bar类,所以我必须实现IFoo接口。

Now I want to to use class Lib::Bar, so I have to implement the IFoo interface.

为了我的目的,我需要一个整体的相关类,所以我想使用一个基类,以保证公共行为使用NVI成语:

For my purposes I need a whole of related classes so I would like to work with a base class that guarantees common behavior using the NVI idiom:

class FooBase : public IFoo // implement interface IFoo
{
    public:
        void method(); // calls methodImpl;

    private:
        virtual void methodImpl();
};

非虚拟接口(NVI)习语应该否定派生类重写公共行为的可能性在 FooBase :: method()中实现,但由于 IFoo 使其虚拟,所有派生类似乎都有机会以覆盖 FooBase :: method()

The non-virtual interface (NVI) idiom ought to deny derived classes the possibility of overriding the common behavior implemented in FooBase::method(), but since IFoo made it virtual it seems that all derived classes have the opportunity to override the FooBase::method().

如果我想使用NVI成语,除了pImpl idiom之外,我已经建议了什么选项(感谢space-c0wb0y)。

If I want to use the NVI idiom, what are my options other than the pImpl idiom already suggested (thanks space-c0wb0y).

推荐答案

我认为你有你的NVI模式错误的方式:
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface

I think you've got your NVI pattern around the wrong way: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface

不确定是否能解决您的问题。

Not sure if that solves your issue though.

class IFoo
{
    public:
       void method() { methodImpl(); }
    private:
       virtual void methodImpl()=0;
};

class FooBase : public IFoo // implement interface IFoo
{
    private:
        virtual void methodImpl();
};

这里有一个例子,为什么你可以使用读取器从XML读取另一个从数据库。注意,公共结构移动到NVI的readFromSource,而非常见的行为移动到私有虚拟getRawDatum。这样,只需要在一个函数中记录日志和错误检查。

Here's an example of why you might do this using a reader that reads from XML and another from DB. Note that common structure is moved into the NVI readFromSource, while non-common behaviour is moved into the private virtual getRawDatum. This way logging and error checking is only needed in the one function.

class IReader
{
  public:
    // NVI
    Datum readFromSource()
    {
       Datum datum = getRawDatum();
       if( ! datum.isValid() ) throw ReaderError("Unable to get valid datum");
       logger::log("Datum Read");
       return datum;
    }
  private:
    // Virtual Bits
    Datum getRawDatum()=0;
};

class DBReader : public IReader
{
  private:
    Datum getRawDatum() { ... }
};

class XmlReader : public IReader
{
   private:
     Datum getRawDatum() { ... }
};

这篇关于如何在C ++中使用非虚拟接口方法实现接口类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆