Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What is an application of private (protected) inheritance?

25 views
Skip to first unread message

Andreas Gieriet

unread,
Jan 11, 2003, 11:57:37 PM1/11/03
to
Hi folks,

inspired by some ongoing threads, I have the following questions:
- can anybody show me a pattern, that is best implemented by
private inheritance?
- is there any useful idiom that is employing private inheritance?

Thanks

Andi
--
Andreas Gieriet mailto:andreas...@externsoft.ch
eXternSoft GmbH http://www.externsoft.com/
Zurlindenstrasse 49 phone:++41 1 454 3077
CH-8003 Zurich/SWITZERLAND fax: ++41 1 454 3078


[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Alexander L. Belikoff

unread,
Jan 12, 2003, 9:11:08 AM1/12/03
to
Andreas Gieriet wrote:
> - is there any useful idiom that is employing private inheritance?

Just to throw in my $0.02: the only thing I understand about private
inheritance is that it defines a IS-IMPLEMENTED-IN-TERMS-OF
relationship.
Which is not like HAS-A relationship, although the latter could be used
to
achieve semantically same thing...

Hope, I'm not stating the obvious...

--
Alexander L. Belikoff GPG f/pr: 0D58 A804 1AB1 4CD8
8DA9
Bloomberg L.P. 424B A86E CD0D 8424
2701
uwmsuk6tv02 <@> sneakemail.com (http://pgp5.ai.mit.edu for
the key)

KIM Seungbeom

unread,
Jan 12, 2003, 10:06:10 AM1/12/03
to
Andreas Gieriet wrote:
>
> inspired by some ongoing threads, I have the following questions:
> - can anybody show me a pattern, that is best implemented by
> private inheritance?
> - is there any useful idiom that is employing private inheritance?

I hope this C++ FAQ Lite topic would be helpful:
[24] Inheritance - private and protected inheritance
http://www.parashift.com/c++-faq-lite/private-inheritance.html

--
KIM Seungbeom <musi...@bawi.org>

Nicolas Fleury

unread,
Jan 12, 2003, 7:13:34 PM1/12/03
to
Andreas Gieriet wrote:
> Hi folks,
>
> inspired by some ongoing threads, I have the following questions:
> - can anybody show me a pattern, that is best implemented by
> private inheritance?
> - is there any useful idiom that is employing private inheritance?

In C++, base classes are initialized before members. If you absolutely
need a private member to be initialized before one of your base classes,
private inheritance instead of aggregation provides a solution.

Regards,

Nicolas Fleury

Joshua Lehrer

unread,
Jan 12, 2003, 11:24:31 PM1/12/03
to
Andreas Gieriet <andreas...@externsoft.ch> wrote in message
news:<3E1FF8AD...@externsoft.ch>...

> Hi folks,
>
> inspired by some ongoing threads, I have the following questions:
> - can anybody show me a pattern, that is best implemented by
> private inheritance?
> - is there any useful idiom that is employing private inheritance?
>

private inheritance is necessary when you wish to have an object as a
private data member, but you need to override a virtual function on
that class. I believe it is useful for implementation inheritence
(vs. interface inheritence), when the implementation requires you to
override virtual functions to control the specific behavior.

joshua lehrer
factset research systems

Andreas Gieriet

unread,
Jan 13, 2003, 8:39:43 AM1/13/03
to
Thanks for all the responses to my question.

I'm aware of how to apply private inheritance from a technical point of view.
It's great to have such a flexibility in the language, but I still don't have
a clue where/how to use it in a meaninful way.

Nicolas Fleury's, do you have a real-life code example (i.e., one that is not
invented for this thread) to show an application - it sounds very interesting.

Any real-life examples are very much appreciated.

Thanks again.

Rob

unread,
Jan 13, 2003, 9:56:16 AM1/13/03
to

"Andreas Gieriet" <andreas...@externsoft.ch> wrote in message
news:3E1FF8AD...@externsoft.ch...
> Hi folks,
>
> inspired by some ongoing threads, I have the following questions:
> - can anybody show me a pattern, that is best implemented by
> private inheritance?
> - is there any useful idiom that is employing private inheritance?
>

RAII (Resource Acquisition Is Initialisation) techniques use classes
with constructors and destructors to impose order on resource management.

A private base class that allocates resources needed by a derived
classes provides a standard means of ensuring the resources are
obtained and released sensibly. Rules in the language (eg order
of construction and destruction) ensure that resources allocated in a
base class will always be cleaned up successfully, even if some error
occurs [i.e. exception thrown] while constructing the derived class.

Private inheritence is usually used in cases where "derived class
is implemented in terms of the base class" but "derived object
can not sensibly be treated as a specialised form of base object".

Maciej Sobczak

unread,
Jan 13, 2003, 9:59:37 AM1/13/03
to
Hi,

"Andreas Gieriet" <andreas...@externsoft.ch> wrote in
message news:3E1FF8AD...@externsoft.ch...

> Hi folks,
>
> inspired by some ongoing threads, I have the following
questions:
> - can anybody show me a pattern, that is best implemented by
> private inheritance?
> - is there any useful idiom that is employing private
inheritance?

The only idiom that I've found useful for me exploits the fact
that base classes (the subobjects of base classes) are
initialized before members and in the order of inheritance
declaration.
Consider this:

class A {};

class B
{
public:
B(const A*);
};

Now I want to have class D, which derives from B. For some
reason, D is also an owner of an object of class A and needs to
pass A's pointer to base class B, when B subobject is
constructed.
The first approach:

class D : public B
{
public:
D() : B(&a_) {}
private:
A a_;
};

is dangerous (well, potentially - it depends on what B's
constructor does with the pointer). The problem is because base
classes are initialized before members, so the subobject of base
class B is constructed before a_ member is constructed. As a
result, B's constructor gets the pointer to the object (a_) that
has its memory already allocated, but has not yet been
constructed. Ouch.

The idiom with private inheritance allows me to work around the
problem:

class D : private A, public B
{
public:
D() : B(this) {}
};

The B's constructor is given a pointer to the whole object, which
is implicitly converted to A* (although MSVC++ warns about "this"
used in initializer list), and because bases are initialized in
the order of inheritance declaration, the pointer points to
already constructed subobject.

Some time ago, James Kanze (IIRC) pointed out that the inventor
of this idiom (which I don't RC) now uses the wrapper around A so
that the D's scope is not polluted with A's members.

This idiom is particularly useful when writing custom stream
classes and this is the only context in which the idiom was
useful for me, experts may wish to say more about this.

When it comes to private inhetitance...
Scott Meyers writes (Effective C++, Item 35) that "no one seems
to know what protected inheritance is supposed to mean"... so why
bother? ;-)

--
Maciej Sobczak
http://www.maciejsobczak.com/

Distributed programming lib for C, C++, Python & Tcl:
http://www.maciejsobczak.com/prog/yami/

Ken Yarnall

unread,
Jan 13, 2003, 12:50:36 PM1/13/03
to
On Mon, 13 Jan 2003 08:39:43 -0500, Andreas Gieriet wrote:

> Thanks for all the responses to my question.
>
> I'm aware of how to apply private inheritance from a technical point
of view.
> It's great to have such a flexibility in the language, but I still
don't have
> a clue where/how to use it in a meaninful way.
>
> Nicolas Fleury's, do you have a real-life code example (i.e., one that
is not
> invented for this thread) to show an application - it sounds very
interesting.
>
> Any real-life examples are very much appreciated.


I found this article awhile back at Object Mentor's site. To be honest,
I
can't recall the details of the pattern, nor do I have time to review,
but
perhaps it will give you what you want...

http://www.objectmentor.com/resources/articles/privateInterface.pdf

Cheers,
Ken

Andreas Gieriet

unread,
Jan 14, 2003, 6:04:57 AM1/14/03
to
Maciej,

Maciej Sobczak schrieb:
>
[snip]


>
> class D : private A, public B
> {
> public:
> D() : B(this) {}
> };
>

I have some reservation for passing a this pointer in an initializer
list (even it is implicitly converted to the already initialized
part of this). I.e., if I see this in a constructor's initializer list,
I rise the read flag - maybe, I have to accept it in the future ...;-)

[snip]


>
> Some time ago, James Kanze (IIRC) pointed out that the inventor
> of this idiom (which I don't RC) now uses the wrapper around A so
> that the D's scope is not polluted with A's members.

What do you mean by this? Does the A-class provide some public interface
that is not intended for inheritance by the D-class?

>
> This idiom is particularly useful when writing custom stream
> classes and this is the only context in which the idiom was
> useful for me, experts may wish to say more about this.
>

Some code example?

> When it comes to private inhetitance...
> Scott Meyers writes (Effective C++, Item 35) that "no one seems
> to know what protected inheritance is supposed to mean"... so why
> bother? ;-)
>

Thanks.

Andi

--
Andreas Gieriet mailto:andreas...@externsoft.ch
eXternSoft GmbH http://www.externsoft.com/
Zurlindenstrasse 49 phone:++41 1 454 3077
CH-8003 Zurich/SWITZERLAND fax: ++41 1 454 3078

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Mark Warren

unread,
Jan 14, 2003, 11:59:03 AM1/14/03
to
"Andreas Gieriet" <andreas...@externsoft.ch> wrote in message
news:3E1FF8AD...@externsoft.ch...
> inspired by some ongoing threads, I have the following questions:
> - can anybody show me a pattern, that is best implemented by
> private inheritance?
> - is there any useful idiom that is employing private inheritance?

Try the following link for a simple example of where it can be used to
avoid
making member functions public.

http://www.objectmentor.com/resources/articles/privateInterface.pdf


Mark

Shannon Barber

unread,
Jan 15, 2003, 5:09:02 AM1/15/03
to
Andreas Gieriet <andreas...@externsoft.ch> wrote in message news:<3E2272A0...@externsoft.ch>...

> Thanks for all the responses to my question.
>
> I'm aware of how to apply private inheritance from a technical point of view.
> It's great to have such a flexibility in the language, but I still don't have
> a clue where/how to use it in a meaninful way.
>
> Nicolas Fleury's, do you have a real-life code example (i.e., one that is not
> invented for this thread) to show an application - it sounds very interesting.
>
> Any real-life examples are very much appreciated.

Hey, I actually have one. At first I thought that I'd never done
that.
Have you ever worked with Windows COM or maybe even WinSockets?
You see, I'm a lazy bastard, so I made two classes that initialize COM
and WinSockets, respectively, in thier ctor's and
shutdown/uninitialize them in thier dtor's. I often inherit them
privately from my main application class. They would work just as
well by protected or public, but leaving it private is easier :)

class SomeWinApp : SGB::COM::CoInitMTA
{
//...
};

struct CoInitMTA
{
public:
CoInitMTA()
{
HRESULT hr;
//If this is undefined, put "#define _WIN32_WINNT 0x0500"
// at the top of your StdAfx.h file - before anything else
//Alternatively, you can use #define _WIN32_WINNT 0x0501 for XP
if(FAILED(hr=CoInitializeEx(NULL, COINIT_MULTITHREADED)))
_com_issue_error(hr);
}

virtual ~CoInitMTA()
{
CoUninitialize();
}
};

Maciej Sobczak

unread,
Jan 15, 2003, 11:57:48 AM1/15/03
to
Hi,

"Andreas Gieriet" <andreas...@externsoft.ch> wrote in

message news:3E23CDBE...@externsoft.ch...


> I have some reservation for passing a this pointer in an
initializer
> list

Your reaction is normal. ;-)
this in the initializer list can mean that the programmer does
not necessarily understand all the consequences of doing so. As
I've written previously, MSVC++ prints a warning (which I do not
like).

Of course, sometimes the programmer *knows* what he's doing and
the fact that some expression is idiomatic (it is recognized by a
larger group of people) relieves the programmer from the need to
justify all his choices beside basic documentation (that can even
be reduced to mere name of idiom in the comment, although I do
not know if this idiom has a name). In other words, once you know
some trick and see it in a couple of places and used by different
people, it stops raising that red flag.

> > Some time ago, James Kanze (IIRC) pointed out that the
inventor
> > of this idiom (which I don't RC) now uses the wrapper around
A so
> > that the D's scope is not polluted with A's members.
>
> What do you mean by this? Does the A-class provide some public
interface
> that is not intended for inheritance by the D-class?

A has its own interface composed of public and protected members.
All are introduced into the scope of deriving class. Once you
derive from A, it is possible that you accidentally use one of
its member, which can be undesirable:

class A
{
public:
void foo();
};

class D : private A
{
public:
void Foo();
void bar()
{
foo(); // <- what do we call?
}
};

Let's say it was a typo and should be "Foo" instead of "foo" in
the commented line. Normally, compiler would flag it as an error,
since there is no "foo" in D. But once you derive from A, it can
be different and not necessarily what the programmer wants.

A wrapper can look like here:

class A_wrapper
{
public:
A * getAPointer() { return &a_; }
private:
A a_;
};

and later:

class D : private A_wrapper, public B
{
// here, there is only getAPointer() in the scope
// so there is less chance for typos

D() : B(getAPointer()) {}
};

A nice side-effect: there is no "this" in the initializer list,
only a function call with self-documenting name.

> > This idiom is particularly useful when writing custom stream
> > classes and this is the only context in which the idiom was
> > useful for me, experts may wish to say more about this.
> >
>
> Some code example?

http://www.maciejsobczak.com/prog/bin/nullstream.zip

The code is extremely short and defines the null-stream, which is
an IOStream equivalent of /dev/null on Unix platforms.

Distributed programming lib for C, C++, Python & Tcl:
http://www.maciejsobczak.com/prog/yami/

KIM Seungbeom

unread,
Jan 16, 2003, 12:28:16 AM1/16/03
to
Ken Yarnall wrote:
>
> I found this article awhile back at Object Mentor's site. To be
honest, I
> can't recall the details of the pattern, nor do I have time to review,
but
> perhaps it will give you what you want...
>
> http://www.objectmentor.com/resources/articles/privateInterface.pdf

Thanks a lot for the enlightening article.

To summarize roughly: a class has some member function that it wants
available only to some specific RequestHandler. It can be achieved by
- separating the interface into Target and RequestInterface,
- making Target privately inherited from RequestInterface, and
- making the request private in Target and public in RequestInterface.

If the inheritance were public, any client could convert Target into
RequestInterface and thus use the request. However, because the
inheritance is private, only Target has control over the conversion
and thus the availability of the request.

This was the first time for me to realise the usefulness of giving
different access specifiers to a set of overriding and overridden
functions, which would apply only to private inheritance.

BTW, I was impressed to see in the article:

Also Known As
I finally found a use for private inheritance.

:)

--
KIM Seungbeom <musi...@bawi.org>

Dave Harris

unread,
Jan 16, 2003, 9:02:24 PM1/16/03
to
andreas...@externsoft.ch (Andreas Gieriet) wrote (abridged):

> - is there any useful idiom that is employing private inheritance?

It's the most direct solution if we need inheritance (because we want to
override virtual functions) but don't want a sub-type relationship. I have
found it useful with the Visitor Pattern.

class Visitor {
public:
virtual void visit_base( Base *b ) = 0;
virtual void visit_sub1( Sub1 *s ) = 0;
virtual void visit_sub2( Sub2 *s ) = 0;
};

class CountTreeNodes : private Visitor {
public:
CountTreeNodes( Base *b ) : count(0) {
b->accept( this );
}

int get_count() const { return count; }

private:
int count;
virtual void visit_base( Base *b ) { count += 1; }
virtual void visit_sub1( Sub1 *s ) { count += 2; }
virtual void visit_sub2( Sub2 *s ) { count += 4; }
};

Another way to write this would be to use a second class that inherits
publicly from Visitor but which is private itself. Some people may prefer
that, but the extra complexity of a second class rarely seems worth it to
me.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

Rob Stewart

unread,
Jan 18, 2003, 5:47:59 AM1/18/03
to
"Maciej Sobczak" <mac...@maciejsobczak.com> wrote in message
news:b023cc$5bb$1...@SunSITE.icm.edu.pl...

> "Andreas Gieriet" <andreas...@externsoft.ch> wrote in
> message news:3E23CDBE...@externsoft.ch...
>
> A nice side-effect: there is no "this" in the initializer list,
> only a function call with self-documenting name.
>
> > > This idiom is particularly useful when writing custom
stream
> > > classes and this is the only context in which the idiom
was
> > > useful for me, experts may wish to say more about this.
> >
> > Some code example?
>
> http://www.maciejsobczak.com/prog/bin/nullstream.zip
>
> The code is extremely short and defines the null-stream, which
is
> an IOStream equivalent of /dev/null on Unix platforms.

But this isn't an appropriate use of private inheritance. Your
GenericNullStream class never needs to masquerade as a NullBuffer
nor use any of NullBuffer's interface. Thus, GenericNullStream
should hold a NullBuffer as a member and pass it's address to
std::basic_stream's ctor.

--
Rob

To reply, change nothing to bigfoot in the address shown.

Andreas Gieriet

unread,
Jan 18, 2003, 6:01:14 AM1/18/03
to
Dave,

this is really new for me. I'm employing the visitor pattern quite often
but never considered to "hide" the visit-methods from the client - he's
not supposed to call them - and I counted on his co-operation.

Basically, it never happend to me, that a client called any visit-method
directly since one can easily hide this as you did it in the constructor.

The bigger problem is usually, that anyone providing a new visitor does
call a visit-method incidently (i.e., instead of the access-method).

Another problem with this approach is the way I am programming visitors:
I usually have a visitor ABC (in most cases, a const-correct
query-visitor; the "accept" method then is named "query").
Then I derive a generic walk-visitor that does the overall
traversing. From that visitor, I derive the specific query-visitors. Most
of the time, these leaf visitors are surprisingly simple, e.g., one
overrides only one or two visit-methods (of totally maybe hundreds).

Ok, I see: this is an application for protected inheritance!
That's it! (Scott, maybe, you can add an errata to "Effective C++ #35" ;-)

Thanks to all!

Cheers,

Andi

Dave Harris schrieb:


>
> andreas...@externsoft.ch (Andreas Gieriet) wrote (abridged):
> > - is there any useful idiom that is employing private inheritance?
>
> It's the most direct solution if we need inheritance (because we want to
> override virtual functions) but don't want a sub-type relationship. I have
> found it useful with the Visitor Pattern.
>
> class Visitor {
> public:
> virtual void visit_base( Base *b ) = 0;
> virtual void visit_sub1( Sub1 *s ) = 0;
> virtual void visit_sub2( Sub2 *s ) = 0;
> };
>
> class CountTreeNodes : private Visitor {
> public:
> CountTreeNodes( Base *b ) : count(0) {
> b->accept( this );
> }
>
> int get_count() const { return count; }
>
> private:
> int count;
> virtual void visit_base( Base *b ) { count += 1; }
> virtual void visit_sub1( Sub1 *s ) { count += 2; }
> virtual void visit_sub2( Sub2 *s ) { count += 4; }
> };
>
> Another way to write this would be to use a second class that inherits
> publicly from Visitor but which is private itself. Some people may prefer
> that, but the extra complexity of a second class rarely seems worth it to
> me.

--


Andreas Gieriet mailto:andreas...@externsoft.ch
eXternSoft GmbH http://www.externsoft.com/
Zurlindenstrasse 49 phone:++41 1 454 3077
CH-8003 Zurich/SWITZERLAND fax: ++41 1 454 3078

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Maciej Sobczak

unread,
Jan 18, 2003, 3:53:16 PM1/18/03
to
Hi,

"Rob Stewart" <robert....@nothing.com> wrote in message
news:F16dnQRuW6u...@comcast.com...

> But this isn't an appropriate use of private inheritance. Your
> GenericNullStream class never needs to masquerade as a
NullBuffer
> nor use any of NullBuffer's interface.

It is true.

> Thus, GenericNullStream
> should hold a NullBuffer as a member and pass it's address to
> std::basic_stream's ctor.

Which is the kind of error I want to avoid in the first place.
The base class std::basic_ostream would be initialized *BEFORE*
the member - then, you would pass to basic_ostream's constructor
a pointer to the object (to member NullBuffer) that was not yet
constructed. May work, but may also end up with undefined
bahavior - there is no guarantee in the standard what the
basic_ostream constructor does with the given pointer.

That's why I show it as an example usage of private inheritance.
It's ugly, but it is a language trick to force the proper order
of initialization. You could even exploit the possibility to have
many private base classes, if more objects are involved in such a
dependency. Yes, it would be even uglier.

Distributed programming lib for C, C++, Python & Tcl:
http://www.maciejsobczak.com/prog/yami/

Dave Harris

unread,
Jan 18, 2003, 6:41:33 PM1/18/03
to
andreas...@externsoft.ch (Andreas Gieriet) wrote (abridged):
> Another problem with this approach is the way I am programming visitors:
> I usually have a visitor ABC (in most cases, a const-correct
> query-visitor; the "accept" method then is named "query").
> Then I derive a generic walk-visitor that does the overall
> traversing. From that visitor, I derive the specific query-visitors.
> Most of the time, these leaf visitors are surprisingly simple, e.g., one
> overrides only one or two visit-methods (of totally maybe hundreds).
>
> Ok, I see: this is an application for protected inheritance!

Perhaps. Although it sounds to me as though the walk-visitor can inherit
from the query-visitor publicly. Both are abstract (in the sense that
instantiating them isn't useful) and I don't see anything gained by
restricting their interfaces. That decision can be left to the subclasses.

So the concrete visitors which inherit from walk-visitor can do so
privately, as in my example. If they have subclasses of their own, it may
make sense to use protected inheritance instead. Although I've used that
for a while (and in a similar kind of visitor hierarchy which separated
type-discovery from traversal), I eventually dropped it as it wasn't
really needed. The concrete visitors never had subclasses of their own.

I think this is fairly common. The visitor class is either abstract,
offering a service for a subclass to customise, or else it is concrete and
does not have subclasses at all. So the access tends to be all or nothing.
Protected inheritance is rare.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Rob Stewart

unread,
Jan 19, 2003, 6:33:05 AM1/19/03
to
From: "Maciej Sobczak" <mac...@maciejsobczak.com>

> "Rob Stewart" <robert....@nothing.com> wrote in message
> news:F16dnQRuW6u...@comcast.com...
>
> > Thus, GenericNullStream
> > should hold a NullBuffer as a member and pass it's address to
> > std::basic_stream's ctor.
>
> Which is the kind of error I want to avoid in the first place.
> The base class std::basic_ostream would be initialized *BEFORE*
> the member - then, you would pass to basic_ostream's
constructor
> a pointer to the object (to member NullBuffer) that was not yet
> constructed. May work, but may also end up with undefined
> bahavior - there is no guarantee in the standard what the
> basic_ostream constructor does with the given pointer.

You make a good point. However, you can pass a null pointer to
the ctor (cf 27.6.1.1.1/1 and then Table 89 (24.4.4.1/3), which
indicates postconditions for std::ios_base::init() when the
streambuf pointer is null, which means a null streambuf pointer
is acceptable.) So, pass a null pointer to the std::ostream
ctor, then, in GenericNullStream's ctor body, pass the address of
the dm to rdbuf().

--
Rob

To reply, change nothing to bigfoot in the address shown.

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Maciej Sobczak

unread,
Jan 19, 2003, 9:14:00 PM1/19/03
to
Hi,

"Rob Stewart" <robert....@nothing.com> wrote in message

news:JeOcnVQam5k...@comcast.com...

> You make a good point. However, you can pass a null pointer to
> the ctor (cf 27.6.1.1.1/1 and then Table 89 (24.4.4.1/3), which
> indicates postconditions for std::ios_base::init() when the
> streambuf pointer is null, which means a null streambuf pointer
> is acceptable.)

(rather 27.6.2.2/1 and 27.4.4.1/3 ;) )

> So, pass a null pointer to the std::ostream
> ctor, then, in GenericNullStream's ctor body, pass the address
of
> the dm to rdbuf().

Rather to init().

Yes, this is something that should work in a decent
implementation.
I have considered this strategy, although I know that there are
people (esp. on this group) that would nit-pick it miserably.

Why?
As you infer from the table 89, the null pointer is allowed,
but... it is a basic_ios::init() and I would need to pass the
pointer to the basic_ostream constructor first.
Whereas the null pointer is allowed in basic_ios::init(), there
is nothing in black and white that guarantees its correctness in
basic_ostream's constructor. It is *very* unlikely that
basic_ostream's constructor would try to do anything with the
given pointer other than just pass it to basic_ios::init() (as
stated in 27.6.2.2/1), but there is also nothing in the Standard
that forbids any additional action (like undocumented checks in
debug mode or something) that would break with null pointer. In
my opinion, IOStreams are underspecified and private inheritance
is politically safer here.

<wink nit-pickability="0">
In addition, private inheritance is
- more funky
- less typing
</wink>

Distributed programming lib for C, C++, Python & Tcl:
http://www.maciejsobczak.com/prog/yami/

0 new messages