2011-04-01 499 views
5

我正在爲一個虛擬rolodex做一個家庭作業項目,這個項目需要一個主類,一個rolodex類和一個卡類。爲了將所有「卡片」的內容輸出到控制檯,分配表明main()應該在rolodex類中調用一個show(...)函數,傳遞一個ostream並顯示(...)然後迭代調用每個showCard()函數。實際顯示是通過卡對象的showCard()函數完成的,顯示在提供的ostream上。C++將ostream作爲參數傳遞

我不明白的是爲什麼ostream會/應該被傳遞到任何地方。好像分配要求是這樣的:

main() { 
    Rolodex myRolodex; 
    ostream myStream; 
    myRolodex.show(myStream); 
} 

void Rolodex::show(ostream& theStream) { 
    //for each card 'i' in the Rolodex... 
    myCard[i].show(theStream); 
} 

void Card::show(ostream& theStream) { 
    theStream << "output some stuff" << endl; 
} 

,而不是像這樣:

main() { 
    Rolodex myRolodex; 
    myRolodex.show(); //no ostream passed 
} 

void Rolodex::show() { 
    //for each card 'i' in the Rolodex... 
    myCard[i].show();//no ostream passed 
} 

void Card::show() { 
    cout << "output some stuff" << endl; 
} 

難道我要麼誤解了使用的ostream作爲參數或缺少其他一些明顯的理由來傳遞像這樣的流下一個ostream?

+0

對於那些相同的,'main'中的第二行需要消失,第三行需要'myRolodex.show(std :: cout);'。 – 2011-04-01 00:30:22

+0

編輯刪除第二個示例中的ostream對象,但爲什麼仍然需要將std :: cout傳遞給Card :: show()?難道它只是使用cout?或者也許同樣你的意思是兩個版本都傳遞一個ostream(不只是相同的輸出)? – ChrisM 2011-04-01 00:38:21

+0

'std :: cout'是一個'ostream'對象。傳遞'std :: ostream'的想法是讓函數不關心它發送輸出的位置。 'std :: cout'只是一個'std :: ostream'的特殊實例。如果你使這個函數本身使用'std :: ostream'的一個實例,你已經擊敗了參數的這一點。 – 2011-04-01 02:45:46

回答

9

我不明白的是爲什麼ostream會/應該被傳遞到任何地方。

這通常用於測試等事情。假設你想要正常輸出控制檯,所以你會傳遞一個對std::cout的引用。但有時候你想做測試,例如單元或驗收測試,並且您希望將輸出存儲在內存中。你可以使用std::stringstream來實現這個功能,而你正在使用的功能並不聰明。

這是一個特定的情況 - 但通常情況下,您想要更改數據源或接收器可能來自何處的任何地方,都可以通過傳遞流來實現。

例如,下面將打印您的Rolodex到控制檯:

int main() 
{ 
    Rolodex myRolodex; 
    myRolodex.show(std::cout); 
} 

...但如果明天你想寫一個文件,而不是,你能做到這一點,而不會影響在裏面的Rolodex代碼所有:

int main() 
{ 
    Rolodex myRolodex; 
    std::ofstream file("This\\Is\\The\\Path\\To\\The\\File.txt"); 
    myRolodex.show(file); // Outputs the result to the file, 
          // rather than to the console. 
} 
2

我只想過載<<操作:

class Card{ 
public: 
    friend ostream& operator<<(ostream& os, const Card& s); 
}; 

ostream& operator<<(ostream& os, const Card& s){ 
    os << "Print stuff"; 
    return os; 
} 

而且你可能會在Rolodex中重載以重複刷卡。