Inherit from cout - how to override "<<" operator & forward to base
Using c++11, but I don't think that matters here.
output.displayHeader() must execute before the inherited from ostream (cout) executes streaming data, or bad things happen. It's of course not as simple as in the example below, and I need to make sure displayHeader() is never missed.
I'm thinking I need to override the "<<" operator, having my own function call displayHeader(), then call the base (cout) "<<" operator. What's the proper syntax for doing this?
I can't call displayHeader() in the constructor, and I can't call it right after the object is defined. There are exception case scenarios where displayHeader() must not be called, and other things must happen instead.
I'm aware this will result in many redundant bool comparisons versus the way I'm doing it now, and I'm perfectly OK with that.
Code:
#include <iostream>
using namespace std;
class myOutput : public ostream {
public:
myOutput() : ostream(cout.rdbuf()) {
}
void displayHeader() {
if(false == displayedHeader) {
*this << "HEADER" << endl;
displayedHeader = true;
}
}
private:
bool displayedHeader { false };
};
int main() {
myOutput output;
output.displayHeader(); // <-- I want this line to go away
output << "Hello" << endl; // <-- By having this line call displayHeader()
output << "Hello, again" << endl; // <-- and likewise this one, but it will see displayedHeader is true
}
Re: Inherit from cout - how to override "<<" operator & forward to base
You can always define an operator<< for your myOutput, that just calls the displayheader, before forwarding to ostream<<:
Code:
#include <iostream>
using namespace std;
class toto
{ };
class myOutput : public ostream {
public:
myOutput()
: ostream(cout.rdbuf())
, displayedHeader(false)
{ }
void displayHeader()
{
if(false == displayedHeader)
{
*this << "HEADER" << endl;
displayedHeader = true;
}
}
private:
bool displayedHeader;
};
template <typename T>
myOutput& operator<<(myOutput& myo, const T& v)
{
myo.displayHeader();
static_cast<std::ostream&>(myo) << v;
return myo;
}
int main() {
myOutput output;
//output.displayHeader(); // <-- I want this line to go away
output << "Hello" << endl; // <-- By having this line call displayHeader()
output << "Hello, again" << endl; // <-- and likewise this one, but it will see displayedHeader is true
}
I'm not 100% sure of the impact afterwards for user writen ostream operators, but I think it should be fine.
Re: Inherit from cout - how to override "<<" operator & forward to base
Quote:
Originally Posted by
monarch_dodra
You can always define an operator<< for your myOutput, that just calls the displayheader, before forwarding to ostream<<:
. . .
I'm not 100% sure of the impact afterwards for user writen ostream operators, but I think it should be fine.
Awesome, thanks! This seems to work well.
I'd also like to make displayHeader() a private function, but it isn't critical, and I can live without it. Is there an easy way to do so? The following code repeatedly runs displayHeader() on my system, deciding that displayedHeader is always false, until the program runs out of memory/hits its maximum allowed memory size. (Without the added red template/friend lines in the class, it runs flawlessly.) I'm assuming I must be triggering an object copy so the original bool is never modified, or something like that, although I can't imagine why it's doing this.
I realize I left displayHeader() public in my example, just wanted to illustrate that adding two lines by themselves caused the issue.
I'm pretty sure the cause is that I don't understand something related to template friend functions, so I doubt the compiler has anything to do with it, but I do run a SVN source build of gcc to keep up with their c++11 implementation. EDIT: Recompiled using system's original gcc 4.1.2, and had the same unexpected behavior.
Code:
#include <iostream>
using namespace std;
class myOutput : public ostream {
public:
myOutput()
: ostream(cout.rdbuf())
, displayedHeader(false)
{ }
void displayHeader()
{
if(false == displayedHeader)
{
*this << "HEADER" << endl;
displayedHeader = true;
}
}
template <typename T>
friend myOutput& operator<<(myOutput& myo, const T& v);
private:
bool displayedHeader;
};
template <typename T>
myOutput& operator<<(myOutput& myo, const T& v)
{
myo.displayHeader();
static_cast<std::ostream&>(myo) << v;
return myo;
}
int main() {
myOutput output;
//output.displayHeader(); // <-- I want this line to go away
output << "Hello" << endl; // <-- By having this line call displayHeader()
output << "Hello, again" << endl; // <-- and likewise this one, but it will see displayedHeader is true
}
Re: Inherit from cout - how to override "<<" operator & forward to base
Quote:
Originally Posted by
darlingm
Code:
void displayHeader()
{
if(false == displayedHeader)
{
*this << "HEADER" << endl;
displayedHeader = true;
}
}
The line in red: This will actually call your template operator<<, which will call displayedHeader, which will call...
There are 2 ways to solve this:
1) The wrong way: Move "displayedHeader = true;" to the line above, this way, the second time you enter it, it breaks the recursive calls.
2) Make an explicit call to ostream's operator<< by casting to ostream:
Code:
void displayHeader()
{
if(false == displayedHeader)
{
static_cast<ostream&>(*this) << "HEADER" << endl;
displayedHeader = true;
}
}
The difference in behavior comes from the fact that in the previous example, the implementation did not "know" about the template.The friend declaration also forward declared it, so that is why it got called.
Had you forward declared the template, or implemented the "displayHeader" in a later .cpp, you would have seen the same behavior.
Re: Inherit from cout - how to override "<<" operator & forward to base
Quote:
Originally Posted by
darlingm
I'm thinking I need to override the "<<" operator, having my own function call displayHeader(), then call the base (cout) "<<" operator.
I think you should reconsider your design as you're using public inheritance the wrong way; consider what happens when you invoke a function taking an ostream& ( like ostream_iterator ctor, for example ... ): your operator<< won't be called breaking your invariants.
You should rewrite your design by overriding the virtual protected interface of streambuf instead.
Re: Inherit from cout - how to override "<<" operator & forward to base
Quote:
Originally Posted by
superbonzo
I think you should reconsider your design as you're using public inheritance the wrong way; consider what happens when you invoke a function taking an ostream& ( like ostream_iterator ctor, for example ... ): your operator<< won't be called breaking your invariants.
You should rewrite your design by overriding the virtual protected interface of streambuf instead.
Very true. I knew there was something fishy somewhere with my approach...
----
To the OP: I think you may want to look into:
http://www.cplusplus.com/reference/iostream/streambuf/
And in particular:
http://www.cplusplus.com/reference/i...eambuf/xsputn/