Topic: iostreams & member/base initialization


Author: jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut)
Date: 20 Sep 1994 13:12:45 -0500
Raw View
I have two questions that have come up because I have been trying to
derive classes from iostreams:

question #1.)

I came across some old code that I had written in one of my earlier attempts
at deriving from ostream.  I did the derivation based on the manual pages
only.  Here is an idea of what I was doing:

class mybuf {
// my stuff here is not really important.
};

class mystream : public ostream {
 mybuf *buf;
public:
 // Note the next line!
 mystream (const Type &var) : ostream (buf = new mybuf (var)) { }
 ~mystream () { delete buf; }
};

Is it legal to initialize mystream::buf in the ctor initializer for
ostream?  It seems to violate the idea of having your base classes
initialized before you can access your members.  It seems to work on
cfront 3.0, but I haven't tried it anywhere else.

question #2.)

On a more recent attempt to derive from ostream, I followed the a paper
called "Iostream Examples" based on a paper by Jerry Schwarz.  The classes
look more like this:

class mybuf {
// my stuff here is not really important.
};

class mybase : virtual public ios {
 mybuf *buf;
public:
 mybase (const Type &var) : {
  buf = new mybuf (var);
  init (buf);
 }
 ~mybase () { delete buf; }
};

class mystream : public mybuf, public ostream {
public:
 mystream (const Type &var) : mybuf (var) { }
};

Although I didn't need to allocate the mybuf dynamically in the mybase
object, I did so to prove my point.  Using purify, I noticed that
the streambuf is accessed during the ios destructor (it causes a free
memory read and shows that the memory was allocated in mybase::mybase.)
Following the order of construction and destruction:
 the ios is constructed.
 the mybase is constructed.
  the mybuf is allocated
  the mybuf is passed to ios::init
 the ostream is constructed
 the mystream is constructed.

 the mystream is destroyed
 the ostream is destroyed
 the mybase is destroyed
  the mybuf is deleted
 the ios is destroyed (and accesses the deleted streambuf)

Even if the mybuf was not dynamically allocated (i.e. is was a member
of the mybase class) it would be destroyed following the mybase destructor
before the ios destructor.  Access to it would be undefined.  Since ios
is part of the standard library, is this a quality of implementation issue?
Is the code for the library delivered to the compiler implementors?  Is there
a way to set up these classes where the streambuf wouldn't be destroyed
before the ios?  If not, who should be made aware of this issue?

Stephen Gevers
sg3235@shelob.sbc.com

PS  I posted this to comp.std.c++ because it involve the standard libraries.
Also, question #1 is a direct question concerning code legality.