2016-04-12 119 views
2

我想打一個類似的行爲有std::cout如何在C++中正確地重載「<<」運算符?

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

我嘗試實施一些事情我剛讀,但它不爲我工作。我想在一個類中實現operator,我稱之爲MyBaseClass。我嘗試這樣做:

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對象中,因此需要支持相同的設置。我還將someOut更改爲std::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