2016-04-12 13 views
2

私はstd::coutのような振る舞いを持つようにしたい:C++で「<<」演算子を正しくオーバーロードする方法は?

int a = 10, b = 15, c = 7; 
MyBaseClass << "a = " << a << ", b = " << b << std::endl; 

私はちょうど読んだが、それは私のために動作しませんいくつかのものを実装してみてください。私はMyBaseClassと呼ぶ1つのクラスにoperatorを実装したいと思います。私はこれを試してみました:

class MyBaseClass { 
    private: 
     std::ostream someOut; 
    public: 
     // My first try: 
     std::ostream &operator<< (std::ostream &out, const std::string &message) { 
     } 

     // The second try: 
     std::ostream &operator<< (const std::string &message) { 
      someOut << message << std::endl; 
      return someOut; 
     } 

     void writeMyOut() { 
      std::cout << someOut.str() 
     }; 
}; 

私はこれをコンパイルするときに私が手:「『MyBaseClass』が暗黙的に欠デフォルトコンストラクタの呼び出し」 - 私はそれを修正するために何をすべきかが必要ですか?

OS X、Xcode、clangコンパイラは、すべて最新です。

+0

可能な[C++初心者を複製方法は、クラスの演算子をオーバーロードするには?](http://stackoverflow.com/questions/2828280/c-beginner-friend-functions-and-operator-overloading-what-is-the-prope) – Joel

+0

私はあなたの秒と思う試してみてください、多かれ少なかれ。コンパイルエラーはおそらく 'MyBaseClass'にコンストラクタがありませんが、' someOut'メンバを初期化する必要があります。 (私はそれが問題だとは100%確信していませんが、もしあなたが 'MyBaseClass'のコンストラクタを提供していれば、あなたはもう少し詳しく知ることができるでしょう、具体的には、初期化されていない'std :: ostream'は' someOut'と呼ばれます) –

+0

@DaveM。 - 空のコンストラクタを追加すると、次のようになります: '型のフィールド 'std :: ostream'(別名 'basic_ostream ')がデフォルトのコンストラクタを保護しました。 ' – JavaRunner

答えて

3

MyBaseClassオブジェクトにさまざまな値タイプを出力しようとしているので、同じセットをサポートする必要があります。また、someOutstd::ostringstreamに変更しました。これは出力を蓄積することができます。正しいとは何か:「友人の機能と<<演算子のオーバーロード - あなたも同様に、それはコンストラクタに渡され、呼び出し側が提供するストリームにstd::ostream&になりたいと思ったかもしれません....

class MyBaseClass { 
    private: 
     std::ostringstream someOut; 
    public: 
     ...other functions... 
     // The second try: 
     template <typename T> 
     MyBaseClass& operator<< (const T& x) { 
      someOut << x; 
      return *this; 
     } 

     void writeMyOut() const { 
      std::cout << someOut.str() 
     }; 
}; 
+0

この場合、 'MyBaseClass'の暗黙的に削除されたデフォルトのコンストラクタを呼び出す – JavaRunner

+0

@JavaRunner: MyBaseClass'のコンストラクタを自分で(おそらくDaveMのプロンプトで)呼び出すことができますか?その場合は削除してください。 'std :: ostream&someOut;で' MyBaseClass(s​​td :: ostream&os):someOut(os){} 'が必要ですが、' std :: ostringstream'にはコンストラクタを指定する必要はありません。 –

+0

ありがとうございます、あなたのソリューションは魅力のように動作します!私の責任です。 – JavaRunner

関連する問題