對於函數聲明一樣如何理解函數的ostream&運算符<<(ostream的和OS,const的無符號字符* S)
ostream& operator<< (ostream& os, const unsigned char* s);
我想知道已經返回了什麼。 CPP參考說它返回ostream對象。但爲什麼它是ostream &,而不是簡單的ostream?
謝謝
對於函數聲明一樣如何理解函數的ostream&運算符<<(ostream的和OS,const的無符號字符* S)
ostream& operator<< (ostream& os, const unsigned char* s);
我想知道已經返回了什麼。 CPP參考說它返回ostream對象。但爲什麼它是ostream &,而不是簡單的ostream?
謝謝
因爲您返回「OS」一樣,你可以做一個鏈接;
std::cout << "string1" << "string2" << std::endl;
返回簡單對象需要編譯器生成對象副本,但返回引用不需要。
操作者返回一個ostream&
(即,可修改參照一個ostream
對象),而不是一個副本或空隙的原因是,它允許鏈接,例如,一個普通的例子與std::cout
作爲ostream
對象:
unsigned int i = 2;
std::cout << "This is a test to print " << "some text and maybe some numbers: " << i << std::endl;
在這裏,我們鏈中的兩個const char*
S,一個unsigned int
和流改性劑,而不必與單獨的線,以它們分開,這使得更好的閱讀和理解。
第一個原因:std::ostream
s通常不可複製(在C++ 11中,複製構造函數實際上是delete
d)。你不想反正返回一個拷貝,因爲鏈接是行不通的:
std::stringstream s;
s << "String1" << "String2";
會失敗,因爲編譯,因爲由第一運營商調用返回的副本不會轉換爲第二次調用所需的參考。
使這兩個值而不是引用也將不起作用:
std::stringstream s;
s << "String1" << "String2";
assert(s.str() == "String1String2");
你的代碼編譯,但因爲對象s
,因爲它是通過複製而不是通過引用傳遞的仍然是這些來電之後未修改斷言將失敗。
第二個原因:您將使用的所有實際stream
對象都從std::ostream
派生。如果這個參數通過複製傳遞,那麼你得到slicing,你有效地丟失了你正在使用的對象。
這意味着下面的代碼將無法正常工作(如果通過引用傳遞,而是由禁止複製回國並以某種方式讓周圍的編譯錯誤?):
std::stringstream s;
s << "String1" << "String2" << std::endl;
assert(s == "String1String2");
s
只會在這種情況下保持"String1"
因爲您在返回時std::stringstream
通過std::ostream
副本,返回的對象不再是std::stringstream
對象,並且調用operator<<
就將"String2"
傳遞給一個臨時對象,該對象最終被破壞。
這些是我可以想到的兩個重要原因,通過引用而不是按價值返回。