Previous fileTop of DocumentContentsIndex pageNext file
Apache C++ Standard Library User's Guide

38.3 Construction and Initialization

All standard stream templates are derived from std::basic_ios. In C++, a virtual base class is initialized by its most derived class; that is, our new odatstream class is responsible for initialization of its base std::basic_ios. Now basic_ios has only one public constructor, which takes a pointer to a stream buffer. This is because basic_ios contains a pointer to the stream buffer, which has to be initialized when a basic_ios subobject is constructed. Consequently, we must figure out how to provide a stream buffer to our base class. Let's consider two options:

38.3.1 Derivation from File Stream or String Stream Classes std::{i,o}fstream or std::{i,o}stringstream

The file and string stream classes contain a stream buffer data member and already monitor the initialization of their virtual base initialization by providing the pointer to their own stream buffer. If we derive from one of these classes, we do not provide another stream buffer pointer because it would be overwritten by the file or string stream's constructor anyway. (Remember that virtual base classes are constructed before non-virtual base classes regardless of where they appear in the hierarchy.) Consider:

The order of initialization would be:

  1. std::ios_base()

  2. std::basic_ios (std::basic_streambuf*)

  3. std::basic_ostream (const char*)

  4. std::basic_ofstream (const char*)

  5. MyOfstream (const char*)

In other words, the constructor of basic_ofstream overwrites the stream buffer pointer set by the constructor of basic_ios.

To avoid this dilemma, class basic_ios has a protected default constructor in addition to its public constructor. This default constructor, which requires a stream buffer pointer, doesn't do anything. Instead, there is a protected initialization function std::basic_ios<>::init() that can be called by any class derived from std::basic_ios<>. With this function, initialization of the std::basic_ios<> base class is handled by the stream class that actually provides the stream buffer -- in our example, std::basic_ofstream<>. It calls the protected init() function:

The order of initialization is:

  1. std::ios_base()

  2. std::basic_ios()

  3. std::basic_ostream (const char*)
    calls std::basic_ios::init(basic_streambuf*)

  4. std::basic_ofstream (const char*)

  5. MyOfstream (const char*)

38.3.2 Derivation from the Stream Classes std::basic_{i,o}stream

The scheme for deriving from the stream classes is slightly different in that you must always provide a pointer to a stream buffer. This is because the stream classes do not contain a stream buffer, as the file or string stream classes do. For example, a class derived from an output stream could look like this:

There are several ways to provide the stream buffer required for constructing such a stream:



Previous fileTop of DocumentContentsIndex pageNext file