I'm a bit confused regarding operator overloading. More specifically, I'm trying to overload the insert operator for the ofstream class so that when I apply it to an object created from one of my classes I can handle the output the way I want. To make a long story short here is an example of what I'm trying to do:
This is the content of the test.log file after program execution:
true-0-
The operator<< function should kick in when program execution runs in an ofstream object on the left side of the << operator that has a boolean variable on it's right side. This behaviour seems to take place only the first time the << operator is used.the second time that the << operator is encountered it's default implementation is called.I'm really puzzled :-)
You should only overload it for ostream, or more generally basic_ostream (if you need wide character support). Since all the fundamental types already are supported by the streams, you should only have to overload it for user-defined types, in which case the correct way is to make it a friend of the class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class my_class {
friend std::ostream& operator<<( std::ostream& os, const my_class& mc ) {
// stuff here
return os;
}
// Or, more generally:
template< typename charT, typename Traits > friend
std::basic_ostream<charT, Traits>& operator<<(
std::basic_ostream<charT, Traits>& os, const my_class& mc ) {
// stuff here
return os;
}
};
Although I think that now I've better understood how operators overloading should be implemented, I still have a doubt.
To learn c++ I'm developing a logging class. Let's say that I need to output log messages (i.e.: strings) using a basic_ostream object and that I would like to be able to change text formatting at will, so that I may be able to output plain or html formatted text.
The log class users shoudn't care about adding formatting characters, the code should handle reformatting for example by transforming string containing "\n" into strings containing "\n<br>" on the fly during the output phase.
I wanted to realize this by overloading operator << for basic_ostream (lhs) and string (rhs) and then , if html mode was enabled, parsing the string to perfomr the needed text sostitutions before outputting it. But in this case if I overload operator<< as described, the compiler complains about the existence of more than one operator<< for the operands...
I'll give you a solution (that you probably won't like), but I'm not _the_ expert on streams, so there might be a better way: create your own stream object that works like cout/cerr. In there you will need to completely reimplement << for all the fundamental types. You'll want to derive your object from ostream (I think, or maybe basic_ostream) so that any user-defined stream output operators are still usable. You'll then want to write one or two manipulators that toggle between HTML and text.
eg, as a user I'd expect to be able to do something like:
clog << html << "This is *boldfaced*\n" << text << "And this is *not*.\n";
Implementing a custom stream object might be a good thing to do in order to learn c++ and theoretically I should only reimplement the << operator only for the types (either basic or user defined) for whoose I need a particular behaviour. I'll try...
If I derive from ostream I get this error while compiling the code:
LogStream.cpp:73: error: 'class LogStream' has no member named 'open'
LogStream.cpp:75: error: 'class LogStream' has no member named 'close'
which sounds correct because the more general ostream class doesn't have methods to handle files. Casting from ostream to ofstream in lines 72 e 73 gives more (uglier) errors (and I do not think is correct to cast a superclass to a subclass...).