Topic: Streams Library
Author: Tiaan Wessels <tiaan@inetsys.alt.za>
Date: 1995/11/07 Raw View
[ Moderator's note:
This post is an incarnation of the Frequently Asked Question
"Why aren't the iostream operators << and >> declared virtual?"
It would be great if someone would write a clear, concise,
and coherent answer to this question for inclusion in the FAQ list.
- moderator (fjh).
]
I have a question regarding the streams library's << and >> operators for
the standard C types. I want to write a class derived from i/ostream and
I want to overload all the operators and member functions. The reason I
want to do this is because my stream will be a network stream and I want
to convert the relevant types to network byte order by calling the
network library's functions inside the ostream& << ( int ) and whatever
member functions of i/ostream wherever byte order will cause a problem.
Furthermore I want to make my own structs streamable in my program by
writing standalone functions taking a i/ostream and my struct as
parameter and streaming it as I want to. The i/ostream parameter is
passed by reference by using the & designator causing dynamic binding
should a derived class of iostream be passed in the place of a standard
stream such as fstream. The operators however were not declared virtual
making what I want to do impossible. Is there any specific reason for
those operators not being virtual ? I don't want to go and redefine
stream operators for my structs for both standard C++ streams and my own
custom streams seperately. If what I'm saying is not clear from this text
I include a small example
class TLIostream : public ostream
{
public:
.
.
ostream& operator<<(const char *s) { // write string out on network }
ostream& operator<<(int n) { // convert n to network byte order and
// write out on tli stream }
.
.
};
struct City
{
char *Name;
int Population;
};
ostream &operator<<( ostream &stream, City c )
{
stream << c.Population << "\t" << c.Name << "\n";
return stream;
}
void main()
{
City c;
ofstream f( "test.file" );
TLIostream t( "192.96.51.58" );
c.Name = new char[20];
strcpy( c.Name, "Downunder" );
c.Population = 200;
f.open( "test.file" );
f << c;
t << c;
f.close();
t.close();
delete c.Name;
}
I would be glad if this was possible however, if I'm not totally of
track, the fact that the operators was not declared virtual in the first
place, makes this impossible.
Tiaan Wessels
tiaan@inetsys.alt.za
Netsys International
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: fuhrmann@weyl.wias-berlin.de (Juergen Fuhrmann)
Date: 1995/11/08 Raw View
>[ Moderator's note: This post is an incarnation of the
> Frequently Asked Question "Why aren't the iostream
> operators << and >> declared virtual?" It would be great
> if someone would write a clear, concise, and coherent
> answer to this question for inclusion in the FAQ list. -
> moderator (fjh). ]
Tiaan> I have a question regarding the streams library's << and >>
Tiaan> operators for the standard C types. I want to write a class
Tiaan> derived from i/ostream and I want to overload all the
Tiaan> operators and member functions. The reason I want to do
Tiaan> this is because my stream will be a network stream and I
Tiaan> want to convert the relevant types to network byte order by
Tiaan> calling the network library's functions inside the ostream&
Tiaan> << ( int ) and whatever member functions of i/ostream
Tiaan> wherever byte order will cause a problem. Furthermore I
Tiaan> want to make my own structs streamable in my program by
Tiaan> writing standalone functions taking a i/ostream and my
Tiaan> struct as parameter and streaming it as I want to. The
Tiaan> i/ostream parameter is passed by reference by using the &
Tiaan> designator causing dynamic binding should a derived class
Tiaan> of iostream be passed in the place of a standard stream
Tiaan> such as fstream. The operators however were not declared
Tiaan> virtual making what I want to do impossible. Is there any
Tiaan> specific reason for those operators not being virtual ? I
Tiaan> don't want to go and redefine stream operators for my
Tiaan> structs for both standard C++ streams and my own custom
Tiaan> streams seperately.
I have the problem that I want to double the output stream, i.e.
to write everything to a protocol file and to the screen (tee(1) would
damage my signal handling). Furthermore, I want to prefix each output line
by a prefix defined per stream and I want to be able to switch streams on and off.
There are some examples in Stroustrup's 2nd edition which led me to the
solution attached below which allows me to use ostream's << operators.
And now, to be not off-topic, how much can I rely on interna of the streams lib
as a virtual overflow(int c) being standard ? (I compiled this with all compilers at hand
(Dec, SGI, g++ and it worked).
Juergen Fuhrmann
Juergen Fuhrmann fuhrmann@wias-berlin.de
Weierstrass Institute for Applied Analysis and Stochastics (WIAS)
Mohrenstrasse 39 D-10117 Berlin, Germany
phone: (49) 030 20377 560 fax: (49) 030 2044975
* Bad News is No News *
//////////////////////////////////////////////////
class DebugStream : public streambuf, public ostream
{
static ostream *prt;
static ostream *out;
int doprefix;
int useprefix;
char *prefix;
...
DebugStream(char *xname,int initial_state) :
streambuf(),
ostream(this)
{
...
}
overflow (int c) // this is the overflow routine from streambuf which _is_ virtual
{
if (!is_on) return 0;
if (doprefix)
{
if (out) *out<< prefix;
if (prt) *prt<< prefix;
doprefix=0;
}
if ((char)c=='\n')
{
if (out)
{
*out << '\n';
out->flush();
}
if (prt)
{
*prt << '\n';
prt->flush();
}
if (useprefix) doprefix=1;
}
else
{
if (out) *out<<(char)c;
if (prt) *prt<<(char)c;
}
return 0;
}
}
--
Juergen Fuhrmann fuhrmann@wias-berlin.de
Weierstrass Institute for Applied Analysis and Stochastics (WIAS)
Mohrenstrasse 39 D-10117 Berlin, Germany
phone: (49) 030 20377 560 fax: (49) 030 2044975
* Bad News is No News *
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]