|
|
When the iostream library is specialized for a new source or sink of characters the natural pattern is this: First derive a class from streambuf, such as fctbuf in the previous subtopic. Then derive classes from whichever of istream, ostream, or iostream is appropriate. For example, suppose we want to do this with the fctbuf class defined in the previous subtopic. The streams might get the definitions:
class fctbase : virtual public ios {
public:
fctbase(action a, open_mode m)
: buf(a,m) { init(&buf) ; }
private:
fctbuf buf ;
} ;
class ifctstream : public fctbase, public istream {
public:
ifctbase(action a)
: fctbase(a, ios::in) { }
} ;
class ofctstream : public fctbase, public ostream {
public:
ofctbase(action a)
: fctbase(a, ios::out) { }
} ;
class iofctstream : public fctbase, public iostream {
public:
iofctstream(action a open_mode m)
: fctbase(a, m) { }
} ;
Derivations from
ios
are virtual so that when the class hierarchy
joins (as it does in
iofctstream)
there will be only one copy of
the error state information.
Because the derivation from
ios
is virtual an argument cannot be
supplied to its constructor.
The
streambuf
is supplied via
ios::init(),
which is a protected member of
ios
intended precisely for this purpose.