• <tfoot id='FYGX9'></tfoot>
    <legend id='FYGX9'><style id='FYGX9'><dir id='FYGX9'><q id='FYGX9'></q></dir></style></legend>
  • <i id='FYGX9'><tr id='FYGX9'><dt id='FYGX9'><q id='FYGX9'><span id='FYGX9'><b id='FYGX9'><form id='FYGX9'><ins id='FYGX9'></ins><ul id='FYGX9'></ul><sub id='FYGX9'></sub></form><legend id='FYGX9'></legend><bdo id='FYGX9'><pre id='FYGX9'><center id='FYGX9'></center></pre></bdo></b><th id='FYGX9'></th></span></q></dt></tr></i><div id='FYGX9'><tfoot id='FYGX9'></tfoot><dl id='FYGX9'><fieldset id='FYGX9'></fieldset></dl></div>
      <bdo id='FYGX9'></bdo><ul id='FYGX9'></ul>

    <small id='FYGX9'></small><noframes id='FYGX9'>

        如何使用 C++ 中的非虚拟接口习语来实现接口类?

        How to implement an interface class using the non-virtual interface idiom in C++?(如何使用 C++ 中的非虚拟接口习语来实现接口类?)
        <legend id='9l7FE'><style id='9l7FE'><dir id='9l7FE'><q id='9l7FE'></q></dir></style></legend>

              1. <i id='9l7FE'><tr id='9l7FE'><dt id='9l7FE'><q id='9l7FE'><span id='9l7FE'><b id='9l7FE'><form id='9l7FE'><ins id='9l7FE'></ins><ul id='9l7FE'></ul><sub id='9l7FE'></sub></form><legend id='9l7FE'></legend><bdo id='9l7FE'><pre id='9l7FE'><center id='9l7FE'></center></pre></bdo></b><th id='9l7FE'></th></span></q></dt></tr></i><div id='9l7FE'><tfoot id='9l7FE'></tfoot><dl id='9l7FE'><fieldset id='9l7FE'></fieldset></dl></div>
                <tfoot id='9l7FE'></tfoot>

                <small id='9l7FE'></small><noframes id='9l7FE'>

                  <bdo id='9l7FE'></bdo><ul id='9l7FE'></ul>

                    <tbody id='9l7FE'></tbody>
                • 本文介绍了如何使用 C++ 中的非虚拟接口习语来实现接口类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  在 C++ 中,接口可以由其方法是纯虚拟的类来实现.

                  In C++ an interface can be implemented by a class whose methods are 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 习语,我还有什么选择(感谢 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_惯用语/非虚拟_接口

                  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 读取的读取器和从 DB 读取的另一个读取器执行此操作.请注意,公共结构移入 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++ 中的非虚拟接口习语来实现接口类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Constructor initialization Vs assignment(构造函数初始化 Vs 赋值)
                  Is a `=default` move constructor equivalent to a member-wise move constructor?(`=default` 移动构造函数是否等同于成员移动构造函数?)
                  Has the new C++11 member initialization feature at declaration made initialization lists obsolete?(声明时新的 C++11 成员初始化功能是否使初始化列表过时了?)
                  Order of constructor call in virtual inheritance(虚继承中构造函数调用的顺序)
                  How to use sfinae for selecting constructors?(如何使用 sfinae 选择构造函数?)
                  Initializing a union with a non-trivial constructor(使用非平凡的构造函数初始化联合)
                    <legend id='dPwYT'><style id='dPwYT'><dir id='dPwYT'><q id='dPwYT'></q></dir></style></legend>

                    <tfoot id='dPwYT'></tfoot>

                    <small id='dPwYT'></small><noframes id='dPwYT'>

                      <tbody id='dPwYT'></tbody>

                            <bdo id='dPwYT'></bdo><ul id='dPwYT'></ul>
                          • <i id='dPwYT'><tr id='dPwYT'><dt id='dPwYT'><q id='dPwYT'><span id='dPwYT'><b id='dPwYT'><form id='dPwYT'><ins id='dPwYT'></ins><ul id='dPwYT'></ul><sub id='dPwYT'></sub></form><legend id='dPwYT'></legend><bdo id='dPwYT'><pre id='dPwYT'><center id='dPwYT'></center></pre></bdo></b><th id='dPwYT'></th></span></q></dt></tr></i><div id='dPwYT'><tfoot id='dPwYT'></tfoot><dl id='dPwYT'><fieldset id='dPwYT'></fieldset></dl></div>