|
|
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 ; } ;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.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) { } } ;