I have three classes: ConsoleInputStream
, ConsoleOutputStream
, ConsoleErrorStream
. All of them are derived from Stream
.
Each stream has virtual functions read
and write
; as you guess, when user tries to use ConsoleInputStream
's write
member function, it throws an error. Same happens when user tries to use ConsoleOutputStream
's write
function.
Now it's time to show the code.
// STREAM.HPP
namespace streamlib {
extern ConsoleInputStream stdin_default;
extern ConsoleOutputStream stdout_default;
extern ConsoleErrorStream stderr_default;
extern Stream& stdin;
extern Stream& stdout;
extern Stream& stderr;
} // namespace streamlib
// STREAM.CPP
namespace streamlib {
ConsoleInputStream stdin_default;
ConsoleOutputStream stdout_default;
ConsoleErrorStream stderr_default;
Stream& stdin = stdin_default;
Stream& stdout = stdout_default;
Stream& stderr = stderr_default;
} // namespace streamlib
// MAIN.CPP
int main()
{
streamlib::stdout = streamlib::stdin;
streamlib::stdout.write(); // Still working, but should have thrown error!
}
However, everything works perfectly well when I define stdin
, stdout
and stderr
as pointers instead of references, i.e. error is thrown as expected. But I don't want to allocate/free memory and use ->
operator where I could (could I?) use plain dot operator.
The real situation is of course even more intricated: I also have some other types derived from Stream
and just want to be able to quickly overload stdin
, stdout
, stderr
streams with different kind of streams. Is it possible to do it with references?
Thanks in advance!
You cannot do with references what you do with pointers, because references cannot be re-assigned. When you do this to references
streamlib::stdout = streamlib::stdin
it corresponds to an assignment of dereferenced pointers, not plain pointers. In other words, if stdout
and stdin
were pointers, the equivalent code would have been
(*streamlib::stdout) = (*streamlib::stdin)
This calls the assignment operator of Stream
, passing stdin
to be assigned to stdout
.
One way around this is to define an assignable "pointer stream" that encapsulates a pointer to a "real" stream, and overrides it on assignment by a pointer to whatever stream being assigned to it. This would let you keep the object syntax, letting you use the dot .
operator instead of the pointer dereference operator ->
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With