I just started learning C++, and I saw some function in C++ primer like that:
double total_receipt(ostream &os)const{...}
then I try to find the address of cout by using this code: "cout << &cout << endl;"
and that's no difference between ostream &os and direct use cout.
So why not just use cout instead of ostream &os? Or maybe it's just a "good" habit?
First notice:
cout is an object (check these docs)
ostream is a class (check these docs)
When you declare a method, you need to use the class names for the parameters, so if your class uses an "output stream" (that's what ostream means) then you declare your function like:
double total_receipt(ostream &os)
You can't create the function like this:
double total_receipt(cout) // doesn't work
Now, if your question is about what is the difference between declaring the total_receipt function like this:
double total_receipt(ostream &os) {
os << "hello world" << std::endl;
}
or like this:
double total_receipt() {
std::cout << "hello world" << std::endl;
}
That's up to you. Usually, we use the first one as that allows to invoke the function with other things besides cout, like:
ofstream out_file("my_file.txt");
total_receipt(out_file);
So, you can pass to that function any object of classes derived from ostream, like ofstream in the example. This means, your function can print to a file, besides printing to the terminal, so you add more functionality if you need it.
Related
Firstly please have a look at some simple codes that my questions derived from.
#include <iostream>
#include <string>
using namespace std;
string get_something()
{
cout << "output something";
return " and return something";
}
void print_something()
{
cout << "print something";
}
int main()
{
cout << get_something(); // will work
cout << print_something(); // will NOT work
return 0;
}
The only different thing I notice between get_something() and print_something() is that one is a return type and one isn't. As you can see I have added comments indicating that which one will work and not work.
However, I am really not sure what is happening behind the scene that makes it one possible and the other not possible.
I am not even sure how I should go about and search for this kind of question too.. so here I am asking a question.
Please enlighten me..
edit:
I am confused that how it is possible to do cout after cout..
both of the functions do that but one of them works and the other doesn't.
This seems to be a very common misunderstanding among beginners. Printing something via cout is not the same as returning a value from a function. Thats completely orthogonal things.
You can write:
std::string returned_value = get_something();
std::cout << returned_value;
But you cannot write:
??? returned_value = print_something();
std::cout << returned_value;
because print_something() does not return anything! void denotes the absence of a type. You cannot have an object of type void.
On the other hand, when you call a function, you can use the returned value (above), or you can ignore it, so this is correct code:
print_something(); // prints something
get_something(); // also print something and returned value is ignored
Note that the function get_something should get a better name, because it is not just "getting" a value. How about print_and_return_something()?
PS:
What I am really confused about is that, how is it possible to do a cout after a cout? Am I just missing what cout actually does?
Not sure If I understand, but I will try... std::cout is an object of type std::ostream. It has an operator<< that you can call, similar to calling methods of other objects. The following two are identical and just use different syntax:
std::cout.operator<<( "Hello World");
std::cout << "Hello World";
When you call print_something() then first the function is executed, then the return value is returned to the caller and execution continues with the caller. This:
std::cout << get_something();
is more or less the same as (well, its a crude simplification, but should be ok here):
// inside get_something
std::cout << "output something";
// return value
std::string result{"output something"};
// now execution continues in caller
std::cout << result;
Calling cout after cout is no different from calling some other function. Suppose you have a function print() that prints something then you can write
std::string print_and_return() {
std::string x{"Hello World"};
print(x);
return x;
}
The caller can do
std::string x = print_and_return(); // <- this already calls print()
print(x); // now we call it again
This is more or less the same as yours, just that I used some hypothetical print() instead of std::cout::operator<<.
Both your functions have a return type. It's just that one of them has a void return type.
The std::ostream class does not have an overload for << that takes a void type. This is sensible - what would be written to the stream in that case?
(cout is an instance of std::ostream that typically writes itself to the standard output which is normally the shell you're using to launch the program.)
Because print_something() has nothing to return, and cout want something to write to the console (the return value it is expecting). Therefore, it will give error.
get_something(), on the other hand, has something to return. So after executing it's rest of line (except return statement) it return the string, which gets printed by cout
get_something() returns something (what seems to be accepted by cout), so cout will receive the returned thing and will work.
On the other hand, print_something() returns nothing (because its return type is void), so cout cannot receive anything to print and won't work.
cout is a stream object.and we use << (insertion operator) to insert value like String,float,Int etc to it which will be displayed in output Screen.Since print_something() is not returning any value so nothing is inserted in stream ,That's why it is not working.
I recommend you to read about Streams in c++ ..
I have a main function that prints a sudoku game to the console as I play. I call a print board method which outputs the board along with a 2D array with the numbers. I've been modifying the game to output to the file after every cout:
cout << "puzzle created" << endl;
output << "puzzle created" << endl;
Then the problem is that there is an error when I try the same with a method:
sudoku.printBoard(); //method to print board to console
I can't simply say:
output << sudoku.printBoard();
and I can't say:
output << "number";
in the method in the board.cpp file either.
Does anyone know any way around this?
This is the problem with print() member functions, and the reason you shouldn't write them. At least, not like this. You've locked yourself into printing to stdout, and now that you want to print somewhere else instead, you're stuck.
Instead, have a function that prints where you tell it to. This may be stdout or a file or whatever.
The function will be declared like this:
void printBoard(std::ostream& os);
and inside its definition, you will use os rather than std::cout.
Then your code will look like this:
sudoku.printBoard(std::cout);
sudoku.printBoard(output);
It works because both std::cout and output are of types that derive from std::ostream.
If you need the cout variant a lot, and you don't want to provide the argument every time because it's getting messy, simply provide an overload:
void printBoard()
{
printBoard(std::cout);
}
Now you can still write:
sudoku.printBoard();
Whether this is more or less confusing for developers on your project is for you to decide.
If you don't have other things to print, so that this is the only function of its kind within the type of sudoku, a more idiomatic approach would be to create an operator<< for that type:
std::ostream& operator<<(std::ostream& os, const SudokuBoard& board)
{
board.printBoard(os);
return os;
}
Now you can use it like this:
std::cout << sudoku;
output << sudoku;
Make a class that takes two ostreams in the constructor. One of these can be std::cout. Store these in the class as references.
Create output stream operators (<<) and use those to write to the two streams.
To use this in other classes pass it as a reference in their constructor (look up dependency injection).
Pass ofstream as a reference to your funtion or simply return string from your function and print it in main() or callee function.
In 2nd case you go like this
string f()
{
ostringstream os;
os<<"whatever I want to print in output";
....
...
return os.str();
}
int main() or //womain() from wherever you call
{
output<<f()<<endl;
}
I am wondering what the reasons and advantages of defining a function with an std::ostream & return type are as opposed to just a void function for printing values. For instance if I wanted to print a string literal I could do it in the following two ways:
std::ostream& print1(std::ostream &os){
os << "print this message";
return os;
}
print1(std::cout);
or
void print2(){
std::cout << "print this message";
}
print2();
Now what would be the advantage of using a function like print1 as opposed to print2? Is one more efficient than the other, and are there other important differences?
The advantage of the first form is that you can for example combine several output functions:
print1(mystream)<<" and that's all !";
More practically, you could easily use file output instead of console output, or even string output. You can also write loops/conditions checking if everything went right, like you would do with standard output functions. Yes, because when you write to a file, things can go wrong (e.g. disk full):
if (! print1(mystream))
cout <<" dik full !?";
But it's just a common practice. You could of course as well choose the second form:
print2(); // yes, put on what stream, always cout ??
if (! cout)
cout <<" oops, unexpected output error...";
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Printing a string to a temporary stream object in C++
std::ostringstream printing the address of the c-string instead of its content
I'm trying to build up a string using stringstream, in the same way you'd use cout. This for something like a logging class. The issue I'm having is that if the first argument to the << operator is a string, when I subsequently print out that stringstream with the stringstream::str() call, I get a garbage address, and not the string. This only occurs with the FIRST string. Subsequent strings are fine. Numbers are always fine. Here's the code:
// class I use to print out the stream
class StreamWriter
{
public:
StreamWriter()
{}
~StreamWriter()
{
std::string myMessage = m_stringstream.str();
std::cout << myMessage << std::endl;
}
std::stringstream m_stringstream;
};
// macro for simplification
#define OSRDEBUG (StreamWriter().m_stringstream)
// actual use
OSRDEBUG << "Hello " << "my " << "name is Pris " << 123456;
// output
0x8054480my name is Pris 123456
0x8054480my name is Pris 123456
0x8054480my name is Pris 123456
0x8054480my name is Pris 123456
Could anyone shed some light on what's going on, and how I could get around the issue?
EDIT:
The following changes (in addition to padiablo's examples) works as well, maintaining the use of the class's destructor with the macro.
// class I use to print out the stream
class StreamWriter
{
public:
StreamWriter()
{ m_stringstream = new std::stringstream; }
~StreamWriter()
{
std::string myMessage = m_stringstream.str();
std::cout << myMessage << std::endl;
delete m_stringstream;
}
std::stringstream * m_stringstream;
};
// macro for simplication
#define OSRDEBUG *(StreamWriter().m_stringstream)
The original question still stands though, because it looks like it should work... and I think it's probably important to know when the times comes to put this into production-quality code.
The problem is indeed that the stream is a temporary.
Before C++11, there was no non-member operator<< overload that took an rvalue reference as the first parameter (aka, allowing writes to temporary streams).
As such, the only valid operator<< overloads were the members, since all non-member overloads take a non-const reference and as such will not bind to temporaries. One of those non-member overloads is the one responsible for printing C strings (aka char const*). Here's one of the member overloads:
basic_ostream<Ch, Traits>& operator<<(void* p);
And guess what your string literal liberally converts to. :)
After the first string, you get a normal reference back from the call to operator<<, which will then allow the non-member overloads to be viable.
I honestly don't understand exactly what's going on (it has something to do with your StreamWriter instance being a temporary), but I see the same effect as paxdiablo described in both GCC and MSVC.
However, here's something that can work around the problem. Add the following helper to your StreamWriter class:
ostream& get_ostream() {
return m_stringstream;
}
and change the macro to:
#define OSRDEBUG (StreamWriter().get_ostream())
I have tried a couple of alternatives, and the only thing I got working is something like this:
#define OSRDEBUG(s) \
do \
{ \
StreamWriter writer; \
writer.m_stringstream << s; \
} while (0)
OSRDEBUG("Hello " << "my " << "name is Pris " << 123456);
I have personally used the above construct for my own logging solutions many times, and seen it done by others as well.
I'm not good enough to know why your example doesn't work, but I guess it has something to do with temporaries not staying alive long enough.
It appears to be a consequence of the way you're instantiating the object. I'm still investigating (and you may get a better answer in the meantime) but explicitly instantiating the object works fine:
#include <iostream>
#include <sstream>
class StreamWriter {
public:
StreamWriter() {}
~StreamWriter() { std::cout << m_stringstream.str() << std::endl; }
std::stringstream m_stringstream;
};
int main (void) {
StreamWriter *sw = new StreamWriter();
sw->m_stringstream << "Hello " << "my " << "name is Pris ";
delete sw;
return 0;
}
As does instantiating on the stack as well:
int main (void) {
StreamWriter sw;
sw.m_stringstream << "Hello " << "my " << "name is Pris ";
return 0;
}
Both of those print out what you expect but the following simplification of your code does not:
int main (void) {
StreamWriter().m_stringstream << "Hello " << "my " << "name is Pris ";
return 0;
}
If you're just after a solution, you can probably get by with:
#define ORSDEBUG StreamWriter sw; sw.m_stringstream
and ensuring you scope-protect the command so that it doesn't try to create more then one sw, and also that it's destroyed at the correct time, same as your original attempt:
{ ORSDEBUG << "Hello " << "my " << "name is Pris"; }
i need someone who explain me these lines of code part by part and i need some help in using "ostream" with simple examples. thank you :).
inline std::ostream& operator<<(std::ostream& os, const Telegram& t)
{
os << "time: " << t.DispatchTime << " Sender: " << t.Sender
<< " Receiver: " << t.Receiver << " Msg: " << t.Msg;
return os;
}
UPDATE 1: when i use this function it doesnt compile and the error says:
std::ostream& class::operator<<(std::ostream& os, const Telegram& t) must take exactly one argument
These line are simply adding the ability to handle Telegram objects to the standard output stream class.
When you add a new class and you want output streams like cout to intelligently handle them, you need to add a new << operator method which has the new object type as the second argument.
What the code above is doing is exactly that. When you later execute the statements:
Telegram tg("Bob", "Hello, how are you?");
cout << tg;
that function in your question will be called with the stream as the first argument and your tg object as the second argument and it will then be able to output the data in a format suitable to the class.
This was actually one of the early C++ things I had trouble getting my head around. Although the class is supposed to be self-contained, you're actually adding something to a different class to handle the output. Once you understand why this is happening (because it's the ostream class that is responsible for outputting things rather than your own class), it will hopefully make sense.
Hopefully making it clearer with a simpler example:
1 inline std::ostream& operator<<(std::ostream& os, const Telegram& t) {
2 os << "message: " << t.Msg;
3 return os;
4 }
Line 1 is simply the function definition. It allows you to return the stream itself (that you pass in) so you can chain << segments. The operator<< is simply the function you're providing, which is the one called when you put << tg into an output stream statement.
Line 2 uses more basic << statements that have already been defined (in this case, whatever type Msg is, probably a string).
Then line 3 returns the stream, again to allow chaining of << segments.
The basic idea is to provide operator<< functions that build on existing operator<< function for the data types that constitute your type.
And with a simple wrapper class containing just an int:
#include <iostream>
// This is my simple class.
class intWrapper {
public:
intWrapper (int x) { myInt = x; };
int getInt (void) { return myInt; }
private:
int myInt;
// Must be friend to access private members.
friend std::ostream& operator<< (std::ostream&, const intWrapper&);
};
// The actual output function.
inline std::ostream& operator<< (std::ostream& os, const intWrapper& t) {
os << "int: " << t.myInt;
return os;
}
// Main program for testing.
// Output with getter and with ostream.
int main (void) {
class intWrapper x(7);
std::cout << x.getInt() << std::endl; // ostream already knows about int.
std::cout << x << std::endl; // And also intWrapper, due to the
// function declared above.
return 0;
}
This outputs:
7
int: 7
the first by just calling the getter function to retrieve the integer, the second by calling the << operator function we added to ostream.
The function you posted (henceforth "the function") is an overload of the insertion operator, operator <<. It allows you to output an object of type Telegram, or any other type deriving from Telegram or convertible to a Telegram, to an output stream. This is similar in spirit to the common use of IO streams in C++:
std::cout << 0 << '\n';
Here you output the int 0 followed by the char newline to the standard output stream. With the function you posted you can now do something like
Telegram tel; // if Telegram has a default constructor
std::cout << tel << '\n';
something you would otherwise not been able to do, because the standard C++ library doesn't know about your new Telegram type and so never defined how to output objects of this type.
In code:
inline std::ostream& operator<<(std::ostream& os, const Telegram& t)
The first line starts with the inline keyword. Presumably the function is defined in a header file, and so in that case you must use the inline keyword so the definition does not violate the one definition rule.
That is, every time you include the header in an implementation file you get the function defined for that implementation file. When the linker comes in to link together all the compiled object files it will find multiple definitions of the function, one in each implementation file that included the header with the function you posted. This is something C++ forbids; C++ demands a function may be implemented no more than one time, and exactly one time if you intend to call it.
The use of the inline keyword essentially asks the C++ compiler to make sure that function is not defined more than once in such a way that the linker jumps off its seat and complains about the ambiguity of multiple definitions to choose from.
Here I argue it's a bad idea to inline the function. It would be a better idea to remove the inline keyword and move the function definition to its own translation unit, or implementation file. This way the function will compile exactly once, as opposed to once for each implementation file that includes the header with the function.
Next you will notice that function is a free function, as opposed to a member function. This allows (requires, as a matter of fact) the function to specify the operator's left operand, the stream object. This means the function will work with any object that is convertible to a stream. It also means you don't need to modify a class to add this extension to output semantics. If the function would be a member then you'd have to change the header of the class, which in turns means recompiling all implementation files that include that header. Granted, it appears your function is defined in a header; that's probably a bad idea, as I explained above.
Next you see that the function returns a std::ostream. std::ostream is in fact typedef'd as std::basic_ostream<char, std::char_traits<char> >, and therefore your function can only output Telegram objects to streams that work on char types.
The reason the function returns a std::ostream is so that you can chain calls to the function. If you look carefully,
std::cout << 0 << 1;
is in fact a chain of two calls to the insertion operator overload function. Once to output 0, and then to output 1. It is equivalent to
std::operator<<(std::operator<<(std::cout, 0), 1);
The first call to insert 0 returns an output stream, and the second call to insert 1 takes that returned output stream and inserts into that 1. That's why we return the output stream: so we can chain calls.
You will also note that the insertion operator has a left-to-right associativity, which means that in the above statement 0 is guaranteed to be output first, and 1 second. This as opposed to the equivalent line I wrote above, in which the associativity (of function calls) is inside-out. This yields a much less readable code IMO, and that's one of the benefits of using operator << for output semantics.
Next look at the function's parameters. The first parameter, a std::ostream, is taken by reference. This so you can change the stream. That's also why the stream is not taken by const reference.
The second parameter can be taken by const reference, because we don't want to change it, just read it. However, we do want to take it by reference, again because we don't intend to change it, not even for a local purpose, and so saving the construction of a copy can only be a good idea. It also allows for accepting derivatives of Telegram and caling virtual functions upon them, should the need arise. Also, taking a const reference allows you to output a temporary, as in std::cout << Telegram() << '\n';.
{
os << "time: " << t.DispatchTime << " Sender: " << t.Sender
<< " Receiver: " << t.Receiver << " Msg: " << t.Msg;
This code should be self explanatory now. Presumably each of the members you insert into the output stream has the insertion operator defined for. The standard library defines insertion into output streams for primitives, for strings, for complex numbers and other standard types.
return os;
}
And finally you return the stream object, so the caller can chain the output with outputting another object. Note that you could simply return the result of the chain:
return os << "time: " << t.DispatchTime << " Sender: " << t.Sender
<< " Receiver: " << t.Receiver << " Msg: " << t.Msg;
Finally, to demonstrate the bonus you get from the use of a free function and taking the Telegram parameter by reference, consider:
struct Telegram {
Telegram();
Telegram(const Communication& c);
virtual ~Telegram();
};
struct Message : public Telegram {
};
struct Letter {
operator Telegram() const;
};
// ...
Telegram t;
Communication c;
Message m;
Letter l;
std::cout << t << '\n'
<< c << '\n'
<< m << '\n'
<< l << '\n';
All using that single function for outputting a Telegram object.