貧弱なC ++ APIについて一言で言えば!

私はずっと前にC ++ APIについて書きたいと思っていましたが、ついにこんばんは。 職業ごとに、私と私は、C ++およびPythonプログラマー用のC ++コードを作成します。これは、当社のすべての製品で使用される機能の中核です。 もちろん、これは、一部の基本構造の言語の違いに関係なく、低レベルC ++と高レベルPythonの両方に共通のロジックを持つコードが直感的なAPIを持たなければならないことを意味します。 Boost.Pythonに関する記事で以前に C ++とPythonの統合について多くのことを書きましたが、今ではPython言語のアーキテクチャとロジックに非常に感謝しています。 C ++、API、およびC ++言語の多くの重要な機能を考慮しない場合に、このような残忍で柔軟な言語を使用して素晴らしいライブラリのインターフェイスでできることについてのみ説明します。



現在の完全な連続



だから、2014年に庭で。 C ++言語(その祖先とは異なり、C言語のサブセット)は、高レベル言語の潜在能力をすべて備えており、長年にわたって潜在能力に過ぎません。 開発者が高レベルの何かを欠いている場合、既成のコードのソースが十分にあるため、自分で何かを発明するか、既成のソリューションを見つける必要があります。 これは古き良きSTLであり、C ++ 11で少し装飾され更新されています。これは、さまざまな準備レベルのさまざまなライブラリを備えた巨大なBoostです。伝染性ライセンス。 C ++ライブラリの豊富さをJavaやPythonのライブラリと比較するつもりはありません。結局、言語はさまざまな問題を解決しますが、C ++で高レベルの何かを書く能力がそれほど難しくないことは誰にとっても明らかです 。 だから、遅かれ早かれ、そのニッチを決定したC ++開発者は、ZenデザインAPIを探して、多くのAPIの雑多な色を単一の一貫した構造に結合する特定の一般的な機能を自分自身または社会、おそらく同僚のために書いています。 もちろん、プログラムインターフェイスを構築することの美しさには興味がなく、世俗的な虚栄心と交換するだけで、有料のコードを書くことだけでライブラリを使用することを好む人もいますが、これは彼らに関するものではありません...さて、耳でこの世界に無理矢理引き寄せられる人のために。



クラス



奇妙なことに、ライブラリのインターフェイスをできるだけ透過的で予測可能なものにしたい場合、APIの非常に弱いリンクはクラスです。 そして、これらの同じクラスのパターンを考慮に入れなくても。 少し歴史に飛び込むと、C ++のクラスはCの構造体構造への単なるアドオンになります。 すべてのフィールドが値で含まれています。つまり、フィールドとOOPアドオンの組み合わせにすぎません。 .NETプラットフォームのC ++言語拡張でManaged C ++に何らかの形で触れた人は誰でも、クラスが参照または値によってデータを参照できることを忘れないでください。 C ++言語と.NETフレームワークの相互作用の複雑さの恐ろしさについては説明しませんが、通常のC ++では、この値が参照またはポインタであっても、クラスデータは常に値によって格納されることに注意してください。 したがって、C言語からそれほど遠くはありません。C言語では、引数が値によって関数に渡され、オプションがなくても、リンクが必要な場合はポインターを渡します。 これはすべて、一時変数をスタックに配置するときに否定できない利点があり、値によるデータの同じ配置は、多かれ少なかれ高レベルのライブラリのアーキテクチャでおそらく最大の問題であり、集中的な開発、新しいバージョンのリリース、および後続の各バージョンとの互換性のあるプログラミングインターフェイスを意味します。 クラス、名前空間、メソッド、フィールドと呼ばれるものは重要ではありません。主なことは、ライブラリのお気に入りのユーザーから実装の詳細を隠す方法です。すべてを知る必要はありません(誰が.cppにクロールする必要があります。 cxxファイルと実装の詳細を参照してください)ヘッダーファイルにはAPI以外は何もないはずなので、可能であれば、不要な#includeをすべて削除し、参照で使用されるすべての型を予備宣言で置き換えてください...

...クラス自体のデータ型を含む!

はい、はい、はい! 参照によってクラスデータを保持できる場合は、データをヘッダーファイルに実装せずに別のクラスとして宣言し、メソッドを実装してデータ全体を.cppファイルに入れることができます。 つまり、クラスのAPIは次のスキームに要約されます。



//       SOME_API  import / export   ( !) //           API ( ,   SOME_API) class SOME_API something { public: //   ,    private: class data; //     ,     SDK,   ,      std::shared_ptr<data> m_data; //   ,     copy-on-write       };
      
      







このコードの類似物は、拡張子に関係なくヘッダーファイルにあります:.h、.hpp、.hxx、またはその不在。 命名は原則ほど重要ではありません。 something ::データクラスの内容に関係なく、someクラスのAPIを使用してファイルを変更することはできません。以前のバージョンとの互換性を失わずにファイルを変更することはできません。 しかし、それだけではありません! ©値による通常のストレージを使用する古典的なアプローチは、水中の岩の全体を運びます。C++言語のフローは、デフォルトでクラスのオブジェクトの動作を運びます。

価値によってストレージの美しさを完全に体験するには、小さな例を考えてみましょう。



 //       SOME_API  class person { public: //           const (     ) void set_name(std::string const& name); // -     ,   STL  MS  std::string   //   ,    copy-on-write,    std::string const& get_name() const; //     vector of child,     ,    //            m_children,     std::vector<person>& get_children(); //           ,       API //       add_child, get_child  .. std::vector<person> const& get_children() const; private: std::string m_name; // -  ,   person std::vector<person> m_children; //   ,     -  };
      
      







ここで何が見えますか? フィールドは標準のSTLコンテナであるため、デフォルトのコンストラクターは、PODタイプの場合に厳しい場合がありますが、ここではかなり許容できます。デフォルトの初期化ではすべて問題ありません。 一般に、コンストラクターには生成されるプロパティがあることに留意してください:デフォルトコンストラクター、コピーコンストラクター、およびC ++ 11では、C ++ 11の移動コンストラクター、コピー演算子、および移動演算子も生成されます。

そして、すべてが初期化と移動のためのSTLのおかげで純粋である場合、同じSTLコンテナのおかげでコピーを行うと、再帰コピーの地獄を取得します。

簡単な操作:



 person neighbour = granny;
      
      





あなたの個人クラスを使用する不幸な開発者の地獄のような頭痛につながる可能性があります。 おばあちゃんの変数には、豊かな子孫を持つ特定の祖母の構築されたオブジェクトがあり、彼女にはたくさんの子供がいて、各子供にはさらに桁違いに孫がいると想像してください。 すべてのルールにより、祖母のこれらの素晴らしい子孫はすべて、アメーバとして隣のオブジェクトにクローンされ始めます。 したがって、C ++ ZenおよびSTLコンテナに関しては祖母にとっては確かに安全ですが、彼女の精神にとっては完全に安全ではなく、クラスを操作する際の基本操作のパフォーマンスを最適化するためにも非常に悪いです。

怠慢な開発者は、「さあ、小さなものではなく、それを理解します」と言うでしょう。そして、不幸なライブラリユーザーは、各オブジェクト内のベクトルをピックアップする方法を考えます。これは、暗黙的なコピーの問題を再帰的に複雑にします。 そしておそらく、彼らはより良く設計され、より透過的で予測可能な動作をする別のライブラリを見つけるでしょう。

明らかな操作での予期しない動作は、機能的な開発者およびAPIデザイナーにとって頭痛の種であり、ライブラリの不幸なユーザーではありません。 極端な場合、経験豊富な開発者は、このような危険なクラスをスマートポインターを使用してラッパーに配置することでこの問題を回避しますが、一般にこれは実行できません。 祖母と彼女の子孫を同期アメーバ分裂から治療しましょう。 このフォームで彼女をここに放置しないでください!



 //     class person { public: //     -,      person(); //  ,    void set_name(std::string const& name); //      // (       !) std::string const& get_name() const; //      // (       !) std::vector<person>& get_children(); //       // (       !) std::vector<person> const& get_children() const; private: class data; //   double dispatch   class data  protected,     std::shared_ptr<data> m_data; //     ,    }; //      ,     class person::data { public: void set_name(std::string const& name); std::string const& get_name() const; std::vector<person>& get_children(); std::vector<person> const& get_children() const; private: std::string m_name; std::vector<person> m_children; }; //     person::person() : m_data(new data) //    , . .     { } //    person    person::data //   -  ,       //  : void person::set_name(std::string const& name) { //  ,      m_data->set_name(name); //    operator->    ,    }
      
      







それで、祖母はコピーを止めました。 絶対に。 また、C ++の概念では完全に正しいわけではありませんが、これについては別途扱います。 原則として、Javaスタイルをベースとして、そのような過酷な値をすべて参照により、参照のみで渡すことができますが、これは、ごまかすことができない状況でライブラリのユーザーをだますことを意味します。 データが変更された場合にのみ、この祖母のデータをコピーできないのはなぜですか?



コピーオンライト



変更時のコピー方法は非常に簡単で、自分で簡単に実装でき、スレッドセーフです(std :: shared_ptr標準C ++ライブラリがスレッドセーフである場合)。 Cowメソッドの本質は次のとおりです。オブジェクトはconstとしてメソッドに渡されますが、データは同じデータから生成されたオブジェクトのすべてのコピー間で共有されます。 ただし、これが非定数になるとすぐに、constとしてマークされていないメソッド(真の例外があります)は、最初にstd :: shared_ptr :: is_unique()をチェックし、複数のオブジェクトが同じデータを参照している場合、一意のフックを解除します一般データのコピーと修正。 原則として、ミューテックスさえ使用せずに、最悪の場合はオブジェクトをもう一度コピーすることができます。これは、このトピックを説明する際のテスト例にとって致命的ではありません。 しかし、このメカニズムは最も単純に実装されます。これは、メカニズムが一般的であるため、中間テンプレートクラスであるテンプレートのこのオブジェクトのconstおよびnon-constケースのoperator->オーバーロードによって実装されます。 この中間テンプレートは次のようになります。



 //   !     ,   ! template <class data> class copy_on_write { public: //   ,      ,    data const* operator -> () const; //  ,    //      ,  ""     data* operator -> (); private: mutable std::shared_ptr<data> m_data; // mutable       const  void ensure_initialized() const; //    void ensure_unique(); //    }; //    template <class data> data const* copy_on_write<data>::operator -> () const { ensure_initialized(); //       nullptr return m_data.get(); //        const- } template <class data> data* copy_on_write<data>::operator -> () { ensure_unique(); // ,         return m_data.get(); //           } template <class data> void copy_on_write<data>::ensure_initialized() const { if (!m_data) { m_data.reset(new data); //    ,      type_traits    } } template <class data> void copy_on_write<data>::ensure_unique() { ensure_initialized(); //        if (!m_data.unique()) //  unique()   std::shared_ptr    { m_data.reset(new data(*m_data)); //        } }
      
      





残っているのは、クラスの人に喜びのために生きる機会を与え、任意の長さの人の処罰されていないベクトルの子孫を作成することです(データへの最初の呼び出しの前に初期化されません)、コピーして、値に関数を渡します(const&は不要ですが、少し高価です) )、値によっても結果として返されます(これもconst&および暗黙的なエラーなし!)しかし、最も重要なことは、オブジェクトのデータを変更し始めると、変更されているオブジェクトのみが再帰的コピーからコピーされることです それは外観のみとなります!

だから、人は、完全な人生を生き、自分自身を否定しないでください:



 class person { public: //   ,     ! private: class data; //      ,       API //              copy_on_write<data> m_data; };
      
      





コピー操作の変更点をまだ理解していないすべての人への簡単な説明。 実際、コピーベクトルのすべての要素は、ソースベクトルの要素と同じデータを参照します。 要素の1つが突然変化し始めた場合、彼は独自のコピーを作成して、すぐにデータのフックを解除します。 したがって、先祖のコピーはそれほど重くはなりませんが、ベクター自体をコピーするとオーバーヘッドが非常に大きくなる可能性があります。



メソッド不変性



もちろん、ベクターへのリンクを発行するメソッドは悪であり、Copy-on-Writeモデルのソリューションとしては非常に失敗します。特に、constおよびnon-constのメソッドのオーバーロードはこれです。 暗黙的なオーバーロードが暗黙的に使用される場合、暗黙的なコピーが存在する可能性があるからです。 結局のところ、APIのユーザーは自分の変数の不変性について心配する必要はありません。たとえば、スタックに変数を設定することにより、開発者は定数でない変数を受け取ります。 したがって、クラスのオブジェクトをコピーする運命が不変性に依存しないことを注意深く監視する必要があります。 少なくとも明白にしましょう。



 class person { public: void set_name(std::string const& name); //  ,        std::string get_name() const; //    std::string      API   int get_child_count() const; //           person get_child(int index) const; //    ,        void add_child(person); //   ,     void set_child(int index, person const& child); //    person      private: class data; //      ,       API //              copy_on_write<data> m_data; };
      
      





合計で、明確なクラスインターフェイスがあり、インスタンスを問題なく大量に作成およびコピーできます。また、少なくとも毎日、ヘッダーファイルを変更せずに実装を変更できます。



APIを使用するときのコンパイル時間



おまけとして、単に人の宣言::データフィールドが実装に隠された別のファイルに配置され、コンパイルする必要がないため、コンパイルが高速化されます。 #include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








  #include ,           person .     std::string    forward declaration,         #include ,        .      : 
      



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








  #include ,           person .     std::string    forward declaration,         #include ,        .      : 
      



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);

, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .












#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








  #include ,           person .     std::string    forward declaration,         #include ,        .      : 
      



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








  #include ,           person .     std::string    forward declaration,         #include ,        .      : 
      



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








  #include ,           person .     std::string    forward declaration,         #include ,        .      : 
      



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");

, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .












#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .








#include , person . std::string forward declaration, #include , . :



// <stdfwd> namespace std { template <typename char_type> class allocator; template <typename char_type> struct char_traits; template <typename char_type, typename traits_type, typename allocator_type> class basic_string; // forward declaration std::string typedef basic_string<char, char_traits<char>, allocator<char>> string; // forward declaration std::wstring typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring; // , #include <cstddef> std::nullptr_t typedef decltype(nullptr) nullptr_t; }






. , C++ API , , . , , , . API.





" " . , : , . , , :

1) API ( , ... , ?)

2) ,

3) - API, .



, .

:



1. , - , - , -, interface- ( ). - . , :



std::unique_ptr<IAmUselessInterface> something = UserUsefulFactory::CreateSomethingLessUseless<DerivedUsefulClass>(arguments);





, , , double dispatch , , - , private. C++ , - , API -.



2. . . 1 . , !.. , , , , - - ! 1 :



std::unique_ptr<I> something = ::Instance().<>( ::Instance().<>(42)); // : (<>(42));





3. . : , , . , : - . , API, - - -, , . , C++ , , - . , , API .



Boost.Python. object namespace boost::python , Python C++, PyObject* , . PyObject* object ( None - NULL - Python). , , boost::python::dict boost::python::object . , , , , dict object .



double dispatch - , , - , ++ . , :



class person { public: // - protected: class data; data& get_data_reference(); data const& get_data_const_reference() const; private: copy_on_write<data> m_data; }; class VIP : public person { public: // protected: class data; // VIP::data - person::data };





:



person president = VIP("mr. President");





, , -.

, , , , . , - !





API, , .

, --API, , ?

! - , - , . , , !





(Copy-on-write).

(Double dispatch)

- , , .











All Articles