Topic: public private inheritance ?


Author: bob.news@gmx.net ("Robert Klemme")
Date: Mon, 27 Jan 2003 09:56:14 +0000 (UTC)
Raw View
"James Kanze" <kanze@gabi-soft.de> schrieb im Newsbeitrag
news:d6651fb6.0301230745.48040afe@posting.google.com...
> bob.news@gmx.net ("Robert Klemme") wrote in message
> news:<b0mm3g$r2o1d$1@ID-52924.news.dfncis.de>...
> > "Pete Becker" <petebecker@acm.org> schrieb im Newsbeitrag
> > news:3E2DA0DE.133F81@acm.org...
> > > Robert Klemme wrote:
>
> > > > I don't like private inheritance much, since it seems to be a
> > > > contradiction in itself: with A privately inheriting B the
> > > > statement "A is a B" does not hold any more - at least from a
> > > > client's view.
>
> > > It's true that private inheritance does not create an 'is a'
> > > relationship. That's not a contradiction.
>
> > Well, normally inheritance is introduced as an "is a" relationship.
> > Although I'd agree, that you *can* define it differently I'd say that
> > we have a contradiction to the *common* definition here.
>
> Everything I've ever read about C++ has said that private inheritance is
> not an isA relationship.

That's exactly what I am saying. My point - if that has not become clear
enough - was just, that there is a contradiction between private
inheritance not beeing "isA" while inheritance generally is viewed as
establishing an "isA" relationship.

> Don't confuse a C++ specific technique, C++ inheritance, with an OO
> concept, which might also be called inheritance.  There is not
> necessarily a direct mapping between C++ constructs and OO concepts, and
> C++ inheritance can be used for many purposes.  The most frequent use of
> public inheritance IS implementing the OO concept of
> derivation/inheritance -- other uses are infrequent enough to require a
> comment.

This distinction is a good point.  Still I feel uncomfortably with private
inheritance since it is a very special case of inheritance that does not
very well match with the general notion of "isA" relationship.

> Another way to consider it is to consider inheritance of what: public
> inheritance is inheritance of the interface, private inheritance is
> inheritance of the implementation.  [...]

When viewing this differentiated, the "beast" becomes less threatening...

> For a more detailed discussion of the why's and wherefore's of public
> vs. private inheritance, see Barton and Nackman.

Thanks for the hint!

Regards

    robert

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kartoffelsack@gmx.net (kartoffelsack)
Date: Thu, 23 Jan 2003 00:33:16 +0000 (UTC)
Raw View
Perhaps inheritance (or even static inheritance) is not the right
expression.

What do you thing about a using declaration for a hole class.

not

class C
:static B           //as suggested by Thomas
{
  //...
};

but

class C
:private B
{
public:
  using B;
};

This is more like you would do it in c++ up to now with the difference
that you don't have to write a using for each public member of B.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ddarius86@hotmail.com (Darius)
Date: Thu, 23 Jan 2003 00:45:23 +0000 (UTC)
Raw View
bob.news@gmx.net ("Robert Klemme") wrote in message news:<b0mm3g$r2o1d$1@ID-52924.news.dfncis.de>...
> "Pete Becker" <petebecker@acm.org> schrieb im Newsbeitrag
> news:3E2DA0DE.133F81@acm.org...
> > Robert Klemme wrote:
> > >
> > > I don't like private inheritance much, since it seems to be a
>  contradiction
> > > in itself: with A privately inheriting B the statement "A is a B" does
>  not
> > > hold any more - at least from a client's view.
> > >
> >
> > It's true that private inheritance does not create an 'is a'
> > relationship. That's not a contradiction.
>
> Well, normally inheritance is introduced as an "is a" relationship.
> Although I'd agree, that you *can* define it differently I'd say that we
> have a contradiction to the *common* definition here.
>
> Regards
>
>     robert

Private (and protected) inheritance _never_ meant "is a".  The only
contradiction you see here is that the term "inheritance" virtually
always means public inheritance as it's the most useful and
interesting.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Thu, 23 Jan 2003 03:48:57 +0000 (UTC)
Raw View
Bob Bell wrote:
> a9804814@unet.univie.ac.at (Thomas Mang) wrote in message news:<3E286B0=
0.8E3C2560@unet.univie.ac.at>...
>=20
>>For example, take this simple classes:
>>
>>class Point2D
>>{
>> public:
>>
>> Point2D(float initX, float initY);
>>
>>// x and y - accessor / manipulator functions
>>
>>private:
>>    float _x;
>>    float _y;
>>};
>>
>>
>>and then derived "public private" Point3D:

I do not like the use of two separated keywords. Maybe this could be the=20
time to give a meaning to protected inheritance ?


>>class Point3D : public private Point2D
>>{
>>public:
>>Point3D(float initX, float initY, float initZ) : Point2D(initX, initY)
>>{}
>>
>>// additional accessor / manipulators for z
>>
>>private:
>>  float _z;
>>};
>>
[...]

> I don't see why this is necessary. Do you have a better example case?

I may have another example where this could be very usefull. Let's say I=20
would like to create a class that is just like a vector, but with some=20
little differences. For example, I might modify the operator[] and the=20
at function to log all their uses.

Currently, I see two ways of doing this, neither of which is fully=20
satisfactory :

- Use public inheritence, document and hope that the user will not=20
delete an instance of the specific vector from a pointer to a=20
std::vector. Since vector are typically managed directly, I believe this=20
is not such a big risk, and this is the solution i would use.

- Use private inheritence, and write zounds of forwarding functions.=20
This solution is ugly to write, and for the reader, the points of=20
interrests are hidden inside lots of "useless" code.

--=20
Lo=EFc

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: petebecker@acm.org (Pete Becker)
Date: Thu, 23 Jan 2003 03:49:30 +0000 (UTC)
Raw View
Robert Klemme wrote:
>
> "Pete Becker" <petebecker@acm.org> schrieb im Newsbeitrag
> news:3E2DA0DE.133F81@acm.org...
> > Robert Klemme wrote:
> > >
> > > I don't like private inheritance much, since it seems to be a
> contradiction
> > > in itself: with A privately inheriting B the statement "A is a B" does
> not
> > > hold any more - at least from a client's view.
> > >
> >
> > It's true that private inheritance does not create an 'is a'
> > relationship. That's not a contradiction.
>
> Well, normally inheritance is introduced as an "is a" relationship.

Only by people who don't know C++.

> Although I'd agree, that you *can* define it differently I'd say that we
> have a contradiction to the *common* definition here.
>

I guess "common" is in the eye of the beholder.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.de (James Kanze)
Date: Thu, 23 Jan 2003 17:48:35 +0000 (UTC)
Raw View
bob.news@gmx.net ("Robert Klemme") wrote in message
news:<b0mm3g$r2o1d$1@ID-52924.news.dfncis.de>...
> "Pete Becker" <petebecker@acm.org> schrieb im Newsbeitrag
> news:3E2DA0DE.133F81@acm.org...
> > Robert Klemme wrote:

> > > I don't like private inheritance much, since it seems to be a
> > > contradiction in itself: with A privately inheriting B the
> > > statement "A is a B" does not hold any more - at least from a
> > > client's view.

> > It's true that private inheritance does not create an 'is a'
> > relationship. That's not a contradiction.

> Well, normally inheritance is introduced as an "is a" relationship.
> Although I'd agree, that you *can* define it differently I'd say that
> we have a contradiction to the *common* definition here.

Everything I've ever read about C++ has said that private inheritance is
not an isA relationship.

Practically, you cannot use it to implement an isA relationship.  An isA
relationship, in the OO sense, means that the derived class can be used
everywhere the base class can; that the derived class "isA" base class.
Since polymorphism in C++ works through pointers and references, this
means that a Derived* or a Derived& must convert implicitly to a Base*
or a Base&, respectively.  This isn't true for a private inheritance.

Don't confuse a C++ specific technique, C++ inheritance, with an OO
concept, which might also be called inheritance.  There is not
necessarily a direct mapping between C++ constructs and OO concepts, and
C++ inheritance can be used for many purposes.  The most frequent use of
public inheritance IS implementing the OO concept of
derivation/inheritance -- other uses are infrequent enough to require a
comment.  IMHO, although rereading some of my own code, I notice that
I'm not all that rigorous about the comment; if the semantics of the
classes is such that isA doesn't apply, then that is generally enough.

Another way to consider it is to consider inheritance of what: public
inheritance is inheritance of the interface, private inheritance is
inheritance of the implementation.  And the isA relationship is only
relevant to the implementation.  Note that this distinction was not
present in many older OO languages, which didn't do static
typechecking; in Smalltalk, all inheritance was implementation (and the
isA relationship was not materialized in the code in any way).  I think
that in the past, there was some confusion about this, because much of
the early work involved GUI's, using the template pattern.  The template
pattern is a special case in which both implementation and interface are
inherited.  More recently, I think that the template pattern has fallen
in disfavor (being largely replaced with delegation), perhaps partially
because of its lack of distinction with regards to the time of
inheritance.

For a more detailed discussion of the why's and wherefore's of public
vs. private inheritance, see Barton and Nackman.

--
James Kanze                           mailto:jkanze@caicheuvreux.com
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kartoffelsack@gmx.net (kartoffelsack)
Date: Thu, 23 Jan 2003 19:11:39 +0000 (UTC)
Raw View
>The using declaration approach allows you to control exactly which
>member functions of the private base are available through the
derived
>class.

But think of generative programming techniques.
With a using for each member-function you cannot work with templates.
With static inheritance as described here you may use a template to
add some attributes, interfaces or whatever to existing classes.

template <typename T>
class C
:static T
{
  //whatever
};

There may be cases when you donot want C to be a T but to uses
everything T has even if you don't know what T will be when designing
C.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Thu, 23 Jan 2003 20:28:56 +0000 (UTC)
Raw View

kartoffelsack schrieb:

> Perhaps inheritance (or even static inheritance) is not the right
> expression.
>
> What do you thing about a using declaration for a hole class.
>
> not
>
> class C
> :static B           //as suggested by Thomas
> {
>   //...
> };
>
> but
>
> class C
> :private B
> {
> public:
>   using B;
> };
>
> This is more like you would do it in c++ up to now with the difference
> that you don't have to write a using for each public member of B.

This is certainly a reasonable alternative. Maybe we can improve it a bit by
using the 'class' keyword too:

class C: private B
{
public:
using class B;
};

Like explicit template instantiations.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Fri, 24 Jan 2003 03:25:01 +0000 (UTC)
Raw View

Bob Bell schrieb:

> a9804814@unet.univie.ac.at (Thomas Mang) wrote in message news:<3E2EA01A.C0775497@unet.univie.ac.at>...
> > Bob Bell schrieb:
> >
> > > >
> > > > Here, Point3D inherits both the interface and the implementation of
> > > > Point2D, without establishing a relationship hierarchie; so there is no
> > > > conversion from Point3D to Point2D.
> > >
> > > I realize that this may be a trivial example, but why is this coupling
> > > between Point2D and Point3D better than defining them as two
> > > independent classes with no coupling between them at all?
> > >
> > > If you really wanted to do this today, you could use private
> > > inheritance and put using declarations within Point3D to make
> > > Point2D's accessors public in Point3D.
> >
> > That's exactly what I want to avoid.
>
> What? Two independent classes, or private inheritance with using
> declarations?

I want to couple them that one is implemented (also in its interface) by the other, but without the using
declarations.
Certainly, if I have one, 2 or very few member functions, using declarations are not such a problem. They are,
however, if the interface gets a bit more complex.


best regards,

Thomas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 22 Jan 2003 07:02:15 +0000 (UTC)
Raw View
a9804814@unet.univie.ac.at (Thomas Mang) wrote in message news:<3E286B00.8E3C2560@unet.univie.ac.at>...
> For example, take this simple classes:
>
> class Point2D
> {
>  public:
>
>  Point2D(float initX, float initY);
>
> // x and y - accessor / manipulator functions
>
> private:
>     float _x;
>     float _y;
> };
>
>
> and then derived "public private" Point3D:
>
> class Point3D : public private Point2D
> {
> public:
> Point3D(float initX, float initY, float initZ) : Point2D(initX, initY)
> {}
>
> // additional accessor / manipulators for z
>
> private:
>   float _z;
> };
>
>
>
> Here, Point3D inherits both the interface and the implementation of
> Point2D, without establishing a relationship hierarchie; so there is no
> conversion from Point3D to Point2D.

I realize that this may be a trivial example, but why is this coupling
between Point2D and Point3D better than defining them as two
independent classes with no coupling between them at all?

If you really wanted to do this today, you could use private
inheritance and put using declarations within Point3D to make
Point2D's accessors public in Point3D.

> The point in the example above is that it has 2 advantages over public
> inheritance:
>
> a) although Point3D has all properties of a Point2D, it's not
> necessarily good to establish an is-a relationship. (and there is code
> where such a relationship does not make sense).
>
> b) Besides the semantic such a hierarchy would introduce, it has also
> effect on the classes layout, because I don't have any virtual functions
> at.all.
> Both classes could be implemented as POD; and for these 2 simple
> classes, the storage advantage / destructor call overhead is quite
> relevant (storage likely to be 50 % / 33% on a 32-bit machine,
> respectively).
>
>
> What do you think about it?

I don't see why this is necessary. Do you have a better example case?

Bob Bell

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Wed, 22 Jan 2003 14:13:38 +0000 (UTC)
Raw View

Bob Bell schrieb:

> >
> > Here, Point3D inherits both the interface and the implementation of
> > Point2D, without establishing a relationship hierarchie; so there is no
> > conversion from Point3D to Point2D.
>
> I realize that this may be a trivial example, but why is this coupling
> between Point2D and Point3D better than defining them as two
> independent classes with no coupling between them at all?
>
> If you really wanted to do this today, you could use private
> inheritance and put using declarations within Point3D to make
> Point2D's accessors public in Point3D.

That's exactly what I want to avoid. I can also use copy&paste to get the same result.
Once the hierarchy gets deeper, these become more error-prone.
Also, each time a base class is updated, potentially all dependent classes have to be changed either.

>
>
> > The point in the example above is that it has 2 advantages over public
> > inheritance:
> >
> > a) although Point3D has all properties of a Point2D, it's not
> > necessarily good to establish an is-a relationship. (and there is code
> > where such a relationship does not make sense).
> >
> > b) Besides the semantic such a hierarchy would introduce, it has also
> > effect on the classes layout, because I don't have any virtual functions
> > at.all.
> > Both classes could be implemented as POD; and for these 2 simple
> > classes, the storage advantage / destructor call overhead is quite
> > relevant (storage likely to be 50 % / 33% on a 32-bit machine,
> > respectively).
> >
> >
> > What do you think about it?
>
> I don't see why this is necessary. Do you have a better example case?

better has relative meaning associated with personal opinion.
I'll give another example:

Say you have some implementation details, which are used by other classes. For example, an allocation
policy.

class AllocationTypeA
{
public:

// operator new / delete here overloaded. Some implementation strategy
};

class AllocationTypeB
{
// operator new / delete here overloaded too, other implementation.
};


Now the strategy is to let other classes derive from one of these two (or others), depending on the
allocation strategy. (You could alternatively assume here any implementation policy that also affects the
interface of the derived class - stream writing / reading functionaly, for example).
The policy is not chosen by clients of the class; in such cases,  templates are certainly a good choice
(like std::allocator in std::vector).

Now say I write a class that perfectly suits to AllocationTypeA, for example because it's optimized for
small objects. To get not only the implementation, but also the interface details of the base class
(overloaded operators), I must use public inheritance (not assuming workarounds such as using-declarations,
or anything else. Once the base class becomes a bit more complex, this becomes cumbersome). That in turn
means a virtual destructor for the base class, and an established Is-A-relationship.

While the second one might be good (and in some cases it certainly is, in some other cases it definitely
isn't), the first one is certainly a burden.
In this example, also the Is-A- relationship is probably not useful; I want to isolate the implementation
details of the classs (which also influences the interface) from clients.
Personnally, the idea came up because of this reason - potential polymorphic use of
not-polymorphic-intended objects.


Another example, somewhat close to my Point2D / Point3D example:

The standard defines a pair-class.

Sometimes we need more but a pair; three,  four, or even more values:

template <typename T, typename U>
class Duo
{
public:
   const T&  First() const;
  const U& Second() const;
};

then Trio:

template <typename T, typename U, typename V>
class Trio : public private Duo<T, U>
{
public:
 const V& Third() const;
};


I think there are examples where a Trio is not necessarily a Duo too.
You can hardly treat a band group consisting of three members as a Duo too, if the third person is the
singer. And similiar examples apply to classes too.

If the name "public private" inheritance scares you (it scares me somewat too), what about "static
inheritance ?"

class Point3D : static Point2D
{};




Please let me apologize for the use of _x, _y, and _z in my points-example.
I do not use this underscored-data-members scheme personally, but I know many use it; so I chose it as best
chance for greatest-common-divisor, but placed the underscore at the wrong side.
It should have certainly be x_, y_ and z_, respectively.


best regards,

Thomas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kartoffelsack@gmx.net (kartoffelsack)
Date: Wed, 22 Jan 2003 18:06:43 +0000 (UTC)
Raw View
That would be very usefull.

You could use it, if you want inheritance but not polymorphy.

It would be a great way of reusing code of existing classes. One could
broaden the interface of a class (some will say: "use non-member
non-friends for that). One could provide one class in a version for
polymorphic use (with a virtual dtor) and one without that overhead.

You can do that now with private inheritance but its hart to maintain
(what if interface chances?).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bob.news@gmx.net ("Robert Klemme")
Date: Wed, 22 Jan 2003 18:06:47 +0000 (UTC)
Raw View
"Pete Becker" <petebecker@acm.org> schrieb im Newsbeitrag
news:3E2DA0DE.133F81@acm.org...
> Robert Klemme wrote:
> >
> > I don't like private inheritance much, since it seems to be a
contradiction
> > in itself: with A privately inheriting B the statement "A is a B" does
not
> > hold any more - at least from a client's view.
> >
>
> It's true that private inheritance does not create an 'is a'
> relationship. That's not a contradiction.

Well, normally inheritance is introduced as an "is a" relationship.
Although I'd agree, that you *can* define it differently I'd say that we
have a contradiction to the *common* definition here.

Regards

    robert

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bob.news@gmx.net ("Robert Klemme")
Date: Wed, 22 Jan 2003 18:27:05 +0000 (UTC)
Raw View
"Thomas Mang" <a9804814@unet.univie.ac.at> schrieb im Newsbeitrag
news:3E2EA01A.C0775497@unet.univie.ac.at...
>
>
> Bob Bell schrieb:
>
> > >
> > > Here, Point3D inherits both the interface and the implementation of
> > > Point2D, without establishing a relationship hierarchie; so there is
no
> > > conversion from Point3D to Point2D.
> >
> > I realize that this may be a trivial example, but why is this coupling
> > between Point2D and Point3D better than defining them as two
> > independent classes with no coupling between them at all?
> >
> > If you really wanted to do this today, you could use private
> > inheritance and put using declarations within Point3D to make
> > Point2D's accessors public in Point3D.
>
> That's exactly what I want to avoid. I can also use copy&paste to get the
same result.

Not quite.  Just making methods visible does not duplicate the code. This
eliminates one major drawback of copy & paste.

> Once the hierarchy gets deeper, these become more error-prone.
> Also, each time a base class is updated, potentially all dependent
classes have to be changed either.

Changing a base class afterwards is often a bad idea.  This would be no
different with your approach.

Regards

    robert

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Thu, 23 Jan 2003 00:31:48 +0000 (UTC)
Raw View

Robert Klemme schrieb:

> "Pete Becker" <petebecker@acm.org> schrieb im Newsbeitrag
> news:3E2DA0DE.133F81@acm.org...
> > Robert Klemme wrote:
> > >
> > > I don't like private inheritance much, since it seems to be a
> contradiction
> > > in itself: with A privately inheriting B the statement "A is a B" does
> not
> > > hold any more - at least from a client's view.
> > >
> >
> > It's true that private inheritance does not create an 'is a'
> > relationship. That's not a contradiction.
>
> Well, normally inheritance is introduced as an "is a" relationship.
> Although I'd agree, that you *can* define it differently I'd say that we
> have a contradiction to the *common* definition here.

IMO, inheritance is a programming strategy/paradigm, whereas
is-a relations are a design property.

In my experience, public inheritance and the resulting hierarchies of related
(convertible) classes is used too often, when is-a does not really hold.
private inheritance means "is-implemented-by", but we don't have a
"shares-properties" inheritance mechanism (well, public inheritance does it,
but as a subset of the whole is-a relation (polymorphism!!), which goes beyond
the shares-a relation(static; no polymorphism) ).

best regards,

Thomas


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: belvis@pacbell.net (Bob Bell)
Date: Thu, 23 Jan 2003 00:32:31 +0000 (UTC)
Raw View
a9804814@unet.univie.ac.at (Thomas Mang) wrote in message news:<3E2EA01A.C0775497@unet.univie.ac.at>...
> Bob Bell schrieb:
>
> > >
> > > Here, Point3D inherits both the interface and the implementation of
> > > Point2D, without establishing a relationship hierarchie; so there is no
> > > conversion from Point3D to Point2D.
> >
> > I realize that this may be a trivial example, but why is this coupling
> > between Point2D and Point3D better than defining them as two
> > independent classes with no coupling between them at all?
> >
> > If you really wanted to do this today, you could use private
> > inheritance and put using declarations within Point3D to make
> > Point2D's accessors public in Point3D.
>
> That's exactly what I want to avoid.

What? Two independent classes, or private inheritance with using
declarations?

Two independent classes, with repeated declarations and definitions,
is indicated when the classes are trivial enough that the risk of
error due to duplication is small compared to the disadvantages of the
extra coupling from having one class inherit from the other.

The using declaration approach allows you to control exactly which
member functions of the private base are available through the derived
class.

> I can also use copy&paste to get the same result.
> Once the hierarchy gets deeper, these become more error-prone.
> Also, each time a base class is updated, potentially all dependent classes have to be changed either.
>
> > > The point in the example above is that it has 2 advantages over public
> > > inheritance:
> > >
> > > a) although Point3D has all properties of a Point2D, it's not
> > > necessarily good to establish an is-a relationship. (and there is code
> > > where such a relationship does not make sense).
> > >
> > > b) Besides the semantic such a hierarchy would introduce, it has also
> > > effect on the classes layout, because I don't have any virtual functions
> > > at.all.
> > > Both classes could be implemented as POD; and for these 2 simple
> > > classes, the storage advantage / destructor call overhead is quite
> > > relevant (storage likely to be 50 % / 33% on a 32-bit machine,
> > > respectively).
> > >
> > >
> > > What do you think about it?
> >
> > I don't see why this is necessary. Do you have a better example case?
>
> better has relative meaning associated with personal opinion.

Well, the Point2D/Point3D example was written off pretty easily. So
what I'm really after is an example that isn't written off so easily
with existing language features.

> I'll give another example:
>
> Say you have some implementation details, which are used by other classes. For example, an allocation
> policy.
>
> class AllocationTypeA
> {
> public:
>
> // operator new / delete here overloaded. Some implementation strategy
> };
>
> class AllocationTypeB
> {
> // operator new / delete here overloaded too, other implementation.
> };
>
>
> Now the strategy is to let other classes derive from one of these two (or others), depending on the
> allocation strategy. (You could alternatively assume here any implementation policy that also affects the
> interface of the derived class - stream writing / reading functionaly, for example).
> The policy is not chosen by clients of the class; in such cases,  templates are certainly a good choice
> (like std::allocator in std::vector).
>
> Now say I write a class that perfectly suits to AllocationTypeA, for example because it's optimized for
> small objects. To get not only the implementation, but also the interface details of the base class
> (overloaded operators), I must use public inheritance (not assuming workarounds such as using-declarations,
> or anything else. Once the base class becomes a bit more complex, this becomes cumbersome). That in turn
> means a virtual destructor for the base class, and an established Is-A-relationship.
>
> While the second one might be good (and in some cases it certainly is, in some other cases it definitely
> isn't), the first one is certainly a burden.
> In this example, also the Is-A- relationship is probably not useful; I want to isolate the implementation
> details of the classs (which also influences the interface) from clients.
> Personnally, the idea came up because of this reason - potential polymorphic use of
> not-polymorphic-intended objects.

class Foo : private AllocationTypeA {

   public:

      using AllocationTypeA::operator new;
      using AllocationTypeA::operator delete;

      // etc.

};

class Bar : private AllocationTypeB {

   public:

      using AllocationTypeB::operator new;
      using AllocationTypeB::operator delete;

      // etc.

};

What's wrong with this?

For that matter, why use inheritance at all?

class Foo {

   public:

      void* operator new(std::size_t size) { return
mAllocator.allocate(size); }
      void operator delete(void* p) { mAllocator.deallocate(p); }

   private:

      AllocationTypeA mAllocator;

};

The second approach has the advantage of allowing per-allocator state,
which isn't allowed in the inheritance method because of the use of
AllocationType::operator new (which is static).

> Another example, somewhat close to my Point2D / Point3D example:
>
> The standard defines a pair-class.
>
> Sometimes we need more but a pair; three,  four, or even more values:
>
> template <typename T, typename U>
> class Duo
> {
> public:
>    const T&  First() const;
>   const U& Second() const;
> };
>
> then Trio:
>
> template <typename T, typename U, typename V>
> class Trio : public private Duo<T, U>
> {
> public:
>  const V& Third() const;
> };
>
>
> I think there are examples where a Trio is not necessarily a Duo too.
> You can hardly treat a band group consisting of three members as a Duo too, if the third person is the
> singer. And similiar examples apply to classes too.
>
> If the name "public private" inheritance scares you (it scares me somewat too), what about "static
> inheritance ?"

It doesn't scare me at all. I'm just not convinced that it's
necessary. There doesn't seem to be a new feature here. So far I
haven't seen anything you can do with "public private" that can't be
done with the existing language.

> Please let me apologize for the use of _x, _y, and _z in my points-example.

No sweat. :-)

Bob

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bob.news@gmx.net ("Robert Klemme")
Date: Tue, 21 Jan 2003 19:15:46 +0000 (UTC)
Raw View
"Thomas Mang" <a9804814@unet.univie.ac.at> schrieb im Newsbeitrag
news:3E286B00.8E3C2560@unet.univie.ac.at...
> Hello everybody,
>
>
> In current C++, we have 4 flavors of inheritance:
>
> public
> protected
> private
> virtual

Not quite: "virtual" rather is a modifier of the other modes.

> I wonder why we don't have something like "public private" inheritance:
> Here, the interface AND the implementation are inherited, but (contrary
> to public inheritance), no relationship is established between
> base/derived class.

You can achieve this today by using private inheritance and then making
selected methods public.

> Personally, I find this idiom quite useful.

I don't like private inheritance much, since it seems to be a contradiction
in itself: with A privately inheriting B the statement "A is a B" does not
hold any more - at least from a client's view.

If I want to inherit functionality then I'd rather use public inheritance -
possibly with a super class without state.

Regards

    robert


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: petebecker@acm.org (Pete Becker)
Date: Tue, 21 Jan 2003 23:54:30 +0000 (UTC)
Raw View
Robert Klemme wrote:
>
> I don't like private inheritance much, since it seems to be a contradiction
> in itself: with A privately inheriting B the statement "A is a B" does not
> hold any more - at least from a client's view.
>

It's true that private inheritance does not create an 'is a'
relationship. That's not a contradiction.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Mon, 20 Jan 2003 18:34:18 +0000 (UTC)
Raw View
Hello everybody,


In current C++, we have 4 flavors of inheritance:

public
protected
private
virtual


public is definitely used most; then I'd guess comes virtual, private,
and protected.


I wonder why we don't have something like "public private" inheritance:
Here, the interface AND the implementation are inherited, but (contrary
to public inheritance), no relationship is established between
base/derived class.

For example, take this simple classes:

class Point2D
{
 public:

 Point2D(float initX, float initY);

// x and y - accessor / manipulator functions

private:
    float _x;
    float _y;
};


and then derived "public private" Point3D:

class Point3D : public private Point2D
{
public:
Point3D(float initX, float initY, float initZ) : Point2D(initX, initY)
{}

// additional accessor / manipulators for z

private:
  float _z;
};



Here, Point3D inherits both the interface and the implementation of
Point2D, without establishing a relationship hierarchie; so there is no
conversion from Point3D to Point2D.

The point in the example above is that it has 2 advantages over public
inheritance:

a) although Point3D has all properties of a Point2D, it's not
necessarily good to establish an is-a relationship. (and there is code
where such a relationship does not make sense).

b) Besides the semantic such a hierarchy would introduce, it has also
effect on the classes layout, because I don't have any virtual functions
at.all.
Both classes could be implemented as POD; and for these 2 simple
classes, the storage advantage / destructor call overhead is quite
relevant (storage likely to be 50 % / 33% on a 32-bit machine,
respectively).


What do you think about it?

Personally, I find this idiom quite useful.

Another example would be low level code, where some shared (by derived
classes) properties are both implementation and interface, but for the
reasons above, public inheritance is to avoid.



best regards,

Thomas




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]