C++ Passing ostream as parameter
Asked Answered
E

2

11

I'm working on a homework project for a virtual rolodex that has called for a main class, a rolodex class, and a card class. To output the contents of all of the "cards" to the console, the assignment says that main() should call a show(...) function in the rolodex class, passing it an ostream and show(...) then iterates over the cards, calling each of their showCard() functions. The actual showing is done by the card objects' showCard() function, showing on the provided ostream.

What I don't understand is why an ostream would/should be passed anywhere. Seems like the assignment is calling for something like this:

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;
}

instead of something like this:

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;
}

Am I either misunderstanding the use of ostream as a parameter or missing some other obvious reason to pass an ostream down the stream like that?

Evered answered 1/4, 2011 at 0:20 Comment(3)
For those to be the same, the second line in main needs to go away, and the third line needs to be myRolodex.show(std::cout);.Rachealrachel
Edited to remove the ostream object in the 2nd example, but why would std::cout still need to be passed down to Card::show()? Can't it just use cout? Or maybe by same you mean both versions pass an ostream around (not just same output)?Evered
std::cout is an ostream object. The idea of passing a std::ostream is to make it so that the function doesn't care where it's sending the output. std::cout is just a special instance of a std::ostream. If you make the function itself use that one instance of std::ostream you've defeated the point of the parameter.Rachealrachel
R
14

What I don't understand is why an ostream would/should be passed anywhere.

This is often used for things like testing. Say you want console output normally, so you'd pass around a reference to std::cout. But sometimes you want to do testing, e.g. unit or acceptance testing, and you want to store the output in memory for that. You could use std::stringstream for this, and the function you're working with is none the wiser.

That's one specific case -- but in general any place where you'd want to change where the data source or sink could be coming from / going to, you can do that by passing a stream around.

For example, the following would print your rolodex to the console:

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

... but if tomorrow you wanted to write to a file instead, you can do that without affecting the code inside Rolodex at all:

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.
}
Rachealrachel answered 1/4, 2011 at 0:24 Comment(0)
P
4

I would just overload the << operator:

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

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

And you could overload in the Rolodex as well to just iterate over the cards.

Pronto answered 6/12, 2015 at 20:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.