2011-04-01 496 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中重载以重复刷卡。