Topic: C++0x Wish List: "parent" keyword


Author: "Pavel Kuznetsov" <pavel@despammed.com>
Date: Mon, 8 Jul 2002 16:15:12 GMT
Raw View
Nate Hayes (nhayes@sunfishstudio.com) wrote:

NH> A long time ago, I used an object-oriented Pascal compiler
NH> from Borland that had a very nice language feature: the "parent"
NH> keyword.

It is interesting that Microsoft introduced keyword '__super'
in the new version of its C++ compiler (aka .NET):

The __super keyword allows you to explicitly state that you are
calling a base-class implementation for a function that you are
overriding. All accessible base-class methods are considered during
the overload resolution phase, and the function that provides the
best match is the one that is called.

__super::member_function();

__super can only appear within the body of a member function.
(...)

Example

// deriv_super.cpp
struct B1 {
   void mf(int) {
      // ...
   }
};

struct B2 {
   void mf(short) {
      // ...
   }

   void mf(char) {
      // ...
   }
};

struct D : B1, B2 {
   void mf(short) {
      __super::mf(1);    // Calls B1::mf(int)
      __super::mf('s');  // Calls B2::mf(char)
   }
};

--
Pavel

---
[ 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: "Nate Hayes" <nhayes@sunfishstudio.com>
Date: Tue, 9 Jul 2002 08:31:36 GMT
Raw View
> It is interesting that Microsoft introduced keyword '__super'
> in the new version of its C++ compiler (aka .NET):

Does the __super keyword also work with virtual methods? Just curious.

Nate



---
[ 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: "Pavel Kuznetsov" <pavel@despammed.com>
Date: Tue, 9 Jul 2002 11:26:15 GMT
Raw View
Nate Hayes (nhayes@sunfishstudio.com) wrote:

>> It is interesting that Microsoft introduced keyword '__super'
>> in the new version of its C++ compiler (aka .NET):

NH> Does the __super keyword also work with virtual methods?
NH> Just curious.

Why not? Sure. Generally, for compiler

  __super::method()

is the same as writing

  CorrespondingBaseClass::method()

--
Pavel

---
[ 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: Bjoern Milcke <Bjoern.Milcke@Sun.COM>
Date: Tue, 9 Jul 2002 17:03:33 GMT
Raw View
"Pavel Kuznetsov" <pavel@despammed.com> writes:

> Nate Hayes (nhayes@sunfishstudio.com) wrote:
>=20
> NH> A long time ago, I used an object-oriented Pascal compiler=20
> NH> from Borland that had a very nice language feature: the "parent"=20
> NH> keyword.
>=20
> It is interesting that Microsoft introduced keyword '__super'
> in the new version of its C++ compiler (aka .NET):
>=20
> The __super keyword allows you to explicitly state that you are=20
> calling a base-class implementation for a function that you are=20
> overriding. All accessible base-class methods are considered during=20
> the overload resolution phase, and the function that provides the=20
> best match is the one that is called.
>=20
> __super::member_function();

As long as you use single inheritance this makes sense (like the
super keyword in Java).

But when you have multiple inheritance, I doubt that when changing
the underlying class structure, that this approach is less error
prone.

> struct D : B1, B2 {
>    void mf(short) {
>       __super::mf(1);    // Calls B1::mf(int)
>       __super::mf('s');  // Calls B2::mf(char)
>    }
> };

Just imagine you would change the parameters of the base class
constructors.

-Bj=F6rn

---
[ 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: igivanov@yahoo.com (Igor Ivanov)
Date: Fri, 5 Jul 2002 22:08:53 GMT
Raw View
"Nate Hayes" <nhayes@sunfishstudio.com> wrote in message news:<uhsofqj21p3b9a@corp.supernews.com>...
> A long time ago, I used an object-oriented Pascal compiler from Borland that
> had a very nice language feature: the "parent" keyword. For example, imagine
> the two classes:
>
[...]

In the current Borland's Object Pascal, the keyword is actually called
"inherited" (which is more appropriate, because it e.g. can be
grandparent). It works like this. If you say

inherited;

it calls the inherited function with the same signature as the
function containing this call;

If you say

inherited foo(arg1);

then the appropriate inherited function will be called.

This works with ctors, dtors and regular functions alike.

Note: in OP, the construction/destruction mechanism is different and
ctors/dtors are never called implicitly.

Igor

---
[ 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: igivanov@yahoo.com (Igor Ivanov)
Date: Fri, 5 Jul 2002 22:09:44 GMT
Raw View
kanze@gabi-soft.de (James Kanze) wrote in message news:<d6651fb6.0207010923.527bde49@posting.google.com>...
[..]
> Actually, I think the reverse is true.  We don't need "super" for the
> normal case, because it can easily be simulated by a typedef.  It

I am not sure what are the criteria for "we need" or "we do not need".
Of course, in C++ you can simulate try/finally, properties, super,
whatever. But eventually things pile up and the programmer forgets to
do some easy and simple thing.

Igor

---
[ 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: "Nate Hayes" <nhayes@sunfishstudio.com>
Date: Sat, 6 Jul 2002 10:20:52 GMT
Raw View
> Note: in OP, the construction/destruction mechanism is different and
> ctors/dtors are never called implicitly.

Its been so long since I've used OP, I can't rememeber. What are the
differences in construction/destruction?

BTW, how does OP interpret the "inherited" keyword when using
multiple-inheritance? I can't even remember if OP supports
multiple-inheritance or not... does it?

Sincerely,

Nate Hayes



---
[ 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: igivanov@yahoo.com (Igor Ivanov)
Date: Mon, 8 Jul 2002 06:15:48 GMT
Raw View
"Nate Hayes" <nhayes@sunfishstudio.com> wrote in message news:<uicrcsgq3gj60@corp.supernews.com>...
> > Note: in OP, the construction/destruction mechanism is different and
> > ctors/dtors are never called implicitly.
>
> Its been so long since I've used OP, I can't rememeber. What are the
> differences in construction/destruction?

(This looks like it's off topic)

The major ones in construction (destruction is similar):
- the ancestor's ctor is not called automatically; you call it
explicitly if you need it and in this case all ctor calls, if any, up
the hierarchy behave as ordinary function calls;
- the object is of the right type from the start, so any calls to
virtual functions even in ancestor ctors or in any other functions are
resolved for this type.

Also note:
- sub-objects have to be constructed explicitly because automatic
construction doesn't exist in OP;
- unlike in C++, in OP you cannot specify the ancestor class in a
call, you can only use the "inherited" keyword.

>
> BTW, how does OP interpret the "inherited" keyword when using
> multiple-inheritance? I can't even remember if OP supports
> multiple-inheritance or not... does it?

There is no MI as in C++, but there are interfaces where you map
interface functions to those of the implementing class; different
kinds of syntax is available for mapping, but the "inherited" is not
used for this.

Regards

Igor

---
[ 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: Alexander Terekhov <terekhov@web.de>
Date: Mon, 8 Jul 2002 08:46:40 GMT
Raw View
Igor Ivanov wrote:
[...]
> - the object is of the right type from the start, so any calls to
> virtual functions even in ancestor ctors or in any other functions are
> resolved for this type.

'mama mia'. But "this type" doesn't exist [zero pre-init aside]! Heck,
if someone really need [I need] polymorphic behavior 'on construction/
destruction'... then [I think] the 'right' place is OPTIONAL *post-*
constructor and *pre-*destructor... garbage collectors [access via GC
pointers 'on destruction' and/or resurrection issues] aside, IMHO.

http://groups.google.com/groups?selm=3D23534C.681063DC%40web.de
(Subject: Re: Constructor Failures)

regards,
alexander.

---
[ 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: Robert Klemme <bob.news@gmx.net>
Date: Wed, 3 Jul 2002 17:12:49 GMT
Raw View

Ken Alverson schrieb:
>
> "Robert Klemme" <bob.news@gmx.net> wrote in message
> news:3D21526F.4FEB2DA5@gmx.net...
> >
> > but in the scenario you describe you want to use tools that
> > handle this anyway.  there are tools for coping with such
> > complexities, that should take a lot of the work from you,
> > especially when it comes to refactoring.  why not just look for
> > such a tool instead of changing the language?  i think others
> > have pointed out the limited usefulness of the concept already...
>
> As long as we're going for complexity, why don't we make it so you have to
> manually chain your constructors and destructors...if you forget to call the
> base class constructor, that subobject never gets constructed.

i don't see how that relates to my statement.  apart from that i
don't think it's an option, because partly constructed instances
would be the consequence.  this would violate a basic invariant
of the language.  and i don't think many people want to do
without it.  :-)

there might be reasons to enforce explicit super class
constructor invocation in a constructor, so a source file would
be in error if these calls were omitted.  i won't opt in favour
of this one, but others might want to.

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: "Ken Alverson" <Ken@Alverson.com>
Date: Wed, 3 Jul 2002 20:21:07 GMT
Raw View
"Robert Klemme" <bob.news@gmx.net> wrote in message
news:3D231BBA.E612AFA7@gmx.net...
> Ken Alverson schrieb:
> >
> > As long as we're going for complexity, why don't we make it so you have
to
> > manually chain your constructors and destructors...if you forget to call
the
> > base class constructor, that subobject never gets constructed.
>
> i don't see how that relates to my statement.  apart from that i
> don't think it's an option, because partly constructed instances
> would be the consequence.  this would violate a basic invariant
> of the language.  and i don't think many people want to do
> without it.  :-)
>
> there might be reasons to enforce explicit super class
> constructor invocation in a constructor, so a source file would
> be in error if these calls were omitted.  i won't opt in favour
> of this one, but others might want to.

Sorry, my sarcasm was appearantly misinterpreted as an actual suggestion.  I
don't think manually chaining constructors and destructors is a good idea.

Manually chaining constructors would open up the same class of bugs as the
"parent" keyword is trying to prevent.  If you had to chain constructors,
and you have two classes, Base and Derived, and later add a class between
them, call it Middleman, there's a nonzero chance that Derived's constructor
would not be updated to construct Middleman, and would instead chain
directly to Base.  Similarly, if we take your suggestion of typedefing
parent and then chaining our function call using that typedef, there's a
nonzero chance that the parent typedef will not be updated.  With a big
project in maintnance mode, this is a valid concern.

On the other hand, if the compiler was resolving the parent call for us,
there's no chaining maintnance to be done, thus the chaining and the
inheritance heirarchy cannot fall out of sync - one implies the other.

Ken


---
[ 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: "d.hope" <dhope@all.com>
Date: Wed, 3 Jul 2002 20:21:35 GMT
Raw View
"Ken Alverson" <Ken@Alverson.com> schreef in bericht
news:afnijj$sn2$1@eeyore.INS.cwru.edu...
> "d.hope" <dhope@all.com> wrote in message
> news:ZqyT8.64785$38.8629548@zwoll1.home.nl...
> > "Nate Hayes" <nhayes@sunfishstudio.com> schreef in bericht
> > news:uhsofqj21p3b9a@corp.supernews.com...
> >
> > <snip>
> >
> > > The "parent" keyword solved this problem.
> >
> > What would the meaning of using the keyword parent be if a class makes
use
> > of multiple inheritance?
>
> How about whatever the definition would be if the current class didn't
> define the member in question.

??? What member in question?

> If that is ambiguous, parent would be too.

???

---
[ 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: "Ken Alverson" <Ken@Alverson.com>
Date: Wed, 3 Jul 2002 22:56:05 GMT
Raw View
"d.hope" <dhope@all.com> wrote in message
news:FfIU8.87229$38.10971721@zwoll1.home.nl...
> "Ken Alverson" <Ken@Alverson.com> schreef in bericht
> news:afnijj$sn2$1@eeyore.INS.cwru.edu...
> > "d.hope" <dhope@all.com> wrote in message
> > news:ZqyT8.64785$38.8629548@zwoll1.home.nl...
> > > "Nate Hayes" <nhayes@sunfishstudio.com> schreef in bericht
> > > news:uhsofqj21p3b9a@corp.supernews.com...
> > > > The "parent" keyword solved this problem.
> > >
> > > What would the meaning of using the keyword parent be if a class makes
> > > use of multiple inheritance?
> >
> > How about whatever the definition would be if the current class didn't
> > define the member in question.
>
> ??? What member in question?

In the case of "parent::foo(...);" the member in question would be
"foo(...)".

So, if you were to have:

class C : public A, public B {
public:
  void foo() {
    parent::foo();
    // do other stuff
  }
};

you would pretend C::foo didn't exist and attempt to resolve the foo member.
In other words, for the purposes of parent resolution, you would pretend
that we're actually working with:

class C : public A, public B {
public:
  void not_foo() {
    foo();
    // do other stuff
  }
};

> > If that is ambiguous, parent would be too.
>
> ???

If we couldn't resolve foo as above (for example, if A and B both defined
foo), the call to parent::foo() would be ambiguous, and would result in a
compile time error.  In such a case, the user would be forced to specify
which parent was inteded, as they would have to currently.

Ken


---
[ 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: Robert Klemme <bob.news@gmx.net>
Date: Thu, 4 Jul 2002 17:53:37 GMT
Raw View

Ken Alverson schrieb:
> Sorry, my sarcasm was appearantly misinterpreted as an actual suggestion.  I
> don't think manually chaining constructors and destructors is a good idea.

oops, i really did not recognize it as sarcasm.  maybe a smily
would have helped me...  :-)

cheers

 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: "Nate Hayes" <nhayes@sunfishstudio.com>
Date: Mon, 1 Jul 2002 22:11:51 GMT
Raw View
>   struct C: A, B {
>     typedef A parent;
>     void f() { parent::f(); std::cout << "C::f()\n"; }
>   };
>
> Couldn't such a typedef solve the problem without the introduction of a
> new keyword (whether it is "parent", "super", "base", or whatever names
> were used in similar proposals...)?

Yes, it might be. I have not tried writing code like that. It is a good
idea. If it actually compiles, then, yes, it would do the trick.

Regarding multiple inheritance, I do not (unfortunately) remember how the
Borland compiler handled that situation. My guess is that if parent::foo()
did not cause an ambiguous method call that it would resolve to the right
parent; if parent::foo() was ambiguous, I suppose the compiler would simply
generate an error.

--nate



---
[ 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: pkl@mailme.dk (Peter Koch Larsen)
Date: Mon, 1 Jul 2002 22:12:12 GMT
Raw View
"Nate Hayes" <nhayes@sunfishstudio.com> wrote in message news:<uhsofqj21p3b9a@corp.supernews.com>...

> A long time ago, I used an object-oriented Pascal compiler from Borland that
> had a very nice language feature: the "parent" keyword. For example, imagine
> the two classes:
>
> class A
> {
>     virtual void foo() { cout << "A::foo()\n"; }
> };
>
> class B : public A
> {
>     virtual void foo() { A::foo(); cout << "B::foo()\n"; }
> };
>
> Now imagine that a new class, C, is created and the inheritance of class B
> is modified as follows:
>
> class A
> {
>     virtual void foo() { cout << "A::foo()\n"; }
> };
>
> class C : public A
> {
>     virtual void foo() { A::foo(); cout << "C::foo()\n"; }
> };
>
> class B : public C
> {
>     virtual void foo() { A::foo(); cout << "B::foo()\n"; }
> };
>
> Notice that a bug has been introduced here. The original intention of
> B::foo() was to first call the base implementation A::foo() and then add
> some functionality. With the insertion of class C into the inheritance
> hierarchy, class B is now "broken" because it no longer invokes the base
> implementation, e.g., it "skips" the base implementation of C::foo() and
> continues to call directly to the base implementation provided by A::foo().
> For example, the program:
>
[output snipped]

> Of course, method B::foo() can be modified as follows:
>
> class B : public C
> {
>     virtual void foo() { C::foo(); cout << "B::foo()\n"; }
> };
>
[output snipped]

> But my experience has been that making such modifications in large class
> libraries can be very cumbersome and error-prone. Indeed it has caused some
> very difficult bugs in large C++ class libraries I've supported.
[snip demonstrating correct behaviour with "parent" keyword snipped]

Hi Nate

Your proposal runs into troubles when multiple inheritance is used.
Which  base-class should "parent" represent? Also, there is an easy
solution, that requires almost no maintenance: declare your own parent
type within the class. This is what your example would look like like:

class B : public A
{
    typedef A parent;
    virtual void foo() { parent::foo(); cout << "B::foo()\n"; }
};


Then, when you change your hirearchy, you only have to change your
parent-definition. You do have to change the type-definition, but the
required change is minor and the lines are close. You could eliminate
the maintenance completely by using a macro or a template, but such an
uglification would not be of my liking.

Kind regards
Peter

---
[ 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: "Ken Alverson" <Ken@Alverson.com>
Date: Mon, 1 Jul 2002 22:11:54 GMT
Raw View
"d.hope" <dhope@all.com> wrote in message
news:ZqyT8.64785$38.8629548@zwoll1.home.nl...
> "Nate Hayes" <nhayes@sunfishstudio.com> schreef in bericht
> news:uhsofqj21p3b9a@corp.supernews.com...
>
> <snip>
>
> > The "parent" keyword solved this problem.
>
> What would the meaning of using the keyword parent be if a class makes use
> of multiple inheritance?

How about whatever the definition would be if the current class didn't
define the member in question.  If that is ambiguous, parent would be too.

Ken


---
[ 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: "Ken Alverson" <Ken@Alverson.com>
Date: Mon, 1 Jul 2002 22:13:21 GMT
Raw View
"James Kanze" <kanze@gabi-soft.de> wrote in message
news:d6651fb6.0207010923.527bde49@posting.google.com...
>
> Actually, I think the reverse is true.  We don't need "super" for the
> normal case, because it can easily be simulated by a typedef.

Can be, but why?  The information is redundant (the compiler clearly knows
the base type) and error prone (if the base changes, you have to modify the
typedef too - if someone forgets you get subtle bugs).

Ken


---
[ 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: "Nate Hayes" <nhayes@sunfishstudio.com>
Date: Mon, 1 Jul 2002 22:13:05 GMT
Raw View
>   struct C: A, B {
>     typedef A parent;
>     void f() { parent::f(); std::cout << "C::f()\n"; }
>   };
>
> Couldn't such a typedef solve the problem without the introduction of a
> new keyword (whether it is "parent", "super", "base", or whatever names
> were used in similar proposals...)?

Yes, it might be. I have not tried writing code like that. It is a good
idea. If it actually compiles, then, yes, it would do the trick.

Regarding multiple inheritance, I do not (unfortunately) remember how the
Borland compiler handled that situation. My guess is that if parent::foo()
did not cause an ambiguous method call that it would resolve to the right
parent; if parent::foo() was ambiguous, I suppose the compiler would simply
generate an error.

--nate





---
[ 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: "Nate Hayes" <nhayes@sunfishstudio.com>
Date: Mon, 1 Jul 2002 22:13:12 GMT
Raw View
> This subject seems to keep coming up.
> Why?
> Something still must be typed!
> If I am unfamilar with the class,
> I have no idea what parent (super ... ) refers to
> without going back and looking it up.
> I would much rather have the base class name right there.
> The only convenience seems to be to the language implimentor.

The main reason I would find some solution to this scenario is due to my
experience supporting and maintaining extremely huge class libraries. In
hierarchies that contain over 80 classes, you have to go back into the
source code and find all methods that invoke parent or "super" methods and
make sure they are correct. If you miss just one of these methods, then it
can cause bugs that are extremely difficult and time consuming to track down
and fix.

I agree that for smaller class libraries, the explicitness of using the base
class name is nice. But the rules are different when dealing with large,
industrial-size class hierarchies.

Sincerley,

Nate



---
[ 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: "Nate Hayes" <nhayes@sunfishstudio.com>
Date: Mon, 1 Jul 2002 22:44:14 GMT
Raw View
> Hi Nate
>
> Your proposal runs into troubles when multiple inheritance is used.
> Which  base-class should "parent" represent?

If you think about it, this is only a problem when ambiguity exists in the
super classes. If there is no ambiguity, then the compiler should be able to
resolve the function call. The troubles begin when foo() is defined in
multiple super classes. In that scenario, I don't know what the compiler
could do except generate an error because of the ambiguity.

> Also, there is an easy
> solution, that requires almost no maintenance: declare your own parent
> type within the class. This is what your example would look like like:
>
> class B : public A
> {
>     typedef A parent;
>     virtual void foo() { parent::foo(); cout << "B::foo()\n"; }
> };
>
>
> Then, when you change your hirearchy, you only have to change your
> parent-definition. You do have to change the type-definition, but the
> required change is minor and the lines are close. You could eliminate
> the maintenance completely by using a macro or a template, but such an
> uglification would not be of my liking.

I think this is a good idea. It still would be nicer, I think, to have a
keyword because then I don't even have to maintain the typedef statements.
But I plan to start using this design in new class hierarchies that I write.
Like you mention, it still has some drawbacks, but at least it localizes all
changes to a single spot in the header file of a class as opposed to
multiple occurences in the implementation file. And that certainly is a step
in the right direction.

It isn't an ideal solution, but it seems to be a very good one if the
"parent" keyword or its equivalent is never added to the language.

Sincerely,

Nate



---
[ 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: "Carl Daniel" <cpdaniel@pacbell.net>
Date: Mon, 1 Jul 2002 22:44:24 GMT
Raw View
"Nate Hayes" <nhayes@sunfishstudio.com> wrote in message
news:uhuighcquii8db@corp.supernews.com...
> Regarding multiple inheritance, I do not (unfortunately) remember how the
> Borland compiler handled that situation. My guess is that if parent::foo()
> did not cause an ambiguous method call that it would resolve to the right
> parent; if parent::foo() was ambiguous, I suppose the compiler would
simply
> generate an error.

The Borland compiler didn't handle it, since Object Pascal doesn't support
multiple inheritance, unlike C++.

-cd


---
[ 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: Robert Klemme <bob.news@gmx.net>
Date: Tue, 2 Jul 2002 02:32:50 CST
Raw View

Nate Hayes schrieb:
> The main reason I would find some solution to this scenario is due to my
> experience supporting and maintaining extremely huge class libraries. In
> hierarchies that contain over 80 classes, you have to go back into the
> source code and find all methods that invoke parent or "super" methods and
> make sure they are correct. If you miss just one of these methods, then it
> can cause bugs that are extremely difficult and time consuming to track down
> and fix.
>
> I agree that for smaller class libraries, the explicitness of using the base
> class name is nice. But the rules are different when dealing with large,
> industrial-size class hierarchies.

but in the scenario you describe you want to use tools that
handle this anyway.  there are tools for coping with such
complexities, that should take a lot of the work from you,
especially when it comes to refactoring.  why not just look for
such a tool instead of changing the language?  i think others
have pointed out the limited usefulness of the concept already...

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: sakrejda@pacbell.net (Grzegorz Sakrejda)
Date: Tue, 2 Jul 2002 15:47:11 GMT
Raw View
"Nate Hayes" <nhayes@sunfishstudio.com> wrote in
<uhsofqj21p3b9a@corp.supernews.com>:

>
>A long time ago, I used an object-oriented Pascal compiler from Borland
>that had a very nice language feature: the "parent" keyword. For
>example, imagine the two classes:
>

  Pascal , as well as java do not have multiple inheritance
  and virtual base classes.

>But my experience has been that making such modifications in large class
>libraries can be very cumbersome and error-prone. Indeed it has caused
>some very difficult bugs in large C++ class libraries I've supported.
>
  Probably C++ needs something similar or better.

>The "parent" keyword solved this problem. Using this keyword, the
>introduction of the thrid class, C, would would have been trivial. For
>example, assume class B had originally been written using the "parent"
>keyword:

 Because of difficulties with multiple inheritance ,
 i would like to see something a little bit different
 but similar to already known C++ constructs .
 The use that you are looking for could be realized by
 member functions that would be generated by compiler in the
 way similar to already known way of generating
 default constructor, copy constructor or assignment operator.
 This would solve difficulties with multiple inheritance
 and virtual base classes.
 Call to this special type of member function would result
 in the call to all matching member functions in the base classes
 in the order determined by construction.
  ( data members should not be  involved )
 This function should not return anything.
 New keyword would have to be introduced to mark the function as such.
 Let's say it will be auto keyword and that auto property is
  inherited. auto doesn't exclude virtual.
Example:
   struct base1 {
     auto init() { std::cout << " base1 " << std::endl; }
     };
    struct base2 : base1 {
     init() { std::cout << "base2 " << std::endl
     };
    struct derived : base1, base2 {
     init() { std::cout << " derived " << std::endl ; }
     };
int main() {
     derived d;
      d.init();
};
    //- result
     base1
     base1
     base2
     derived

 Few other uses :

 Object streaming - reading /writing object from/to the stream
     should be done in order of construction.
  Ability to define such automatic member function would
    simplify this by delegating work to member function up
     the inheritance tree.

 struct Object : base1,base2 ... {
     t1 dat1;
     //auto
    void read(istream& is) { is >> dat1; } // that would be all
    };

 Post constructors - automatic initialization of
     abstract base classes
   using arguments supplied by derived class :

  struct interface {
     virtual argtype getarg()=0;
     void initialize(argtype arg) {.. }
     auto void init() { initialize(getarg()); }
     };
   struct derived : interface1,interface2... {
     argtype getarg() { return argtype(); }
     derived() { init(); }
     };
  We need to call init here, but this will initialize all
   interfaces without the need to do it more explicitly.

 Improved encapsulation seems to be the result.

  grzegorz

---
[ 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: "Mike Schilling" <mscottschilling@hotmail.com>
Date: Tue, 2 Jul 2002 15:49:54 GMT
Raw View
"Nate Hayes" <nhayes@sunfishstudio.com> wrote in message
news:ui0o4k4itu1cd5@corp.supernews.com...
> >   struct C: A, B {
> >     typedef A parent;
> >     void f() { parent::f(); std::cout << "C::f()\n"; }
> >   };
> >
> > Couldn't such a typedef solve the problem without the introduction of a
> > new keyword (whether it is "parent", "super", "base", or whatever names
> > were used in similar proposals...)?
>
> Yes, it might be. I have not tried writing code like that. It is a good
> idea. If it actually compiles, then, yes, it would do the trick.

It's a well-known trick.  In _D & E_, Stroustrup gives its existence as the
reason the "super" keyword isn't required in 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: "Ken Alverson" <Ken@Alverson.com>
Date: Tue, 2 Jul 2002 15:50:05 GMT
Raw View
"Robert Klemme" <bob.news@gmx.net> wrote in message
news:3D21526F.4FEB2DA5@gmx.net...
>
> but in the scenario you describe you want to use tools that
> handle this anyway.  there are tools for coping with such
> complexities, that should take a lot of the work from you,
> especially when it comes to refactoring.  why not just look for
> such a tool instead of changing the language?  i think others
> have pointed out the limited usefulness of the concept already...

As long as we're going for complexity, why don't we make it so you have to
manually chain your constructors and destructors...if you forget to call the
base class constructor, that subobject never gets constructed.

Of course, then we could write tools to maintain it for us.

Ken


---
[ 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: "Nate Hayes" <nhayes@sunfishstudio.com>
Date: Sun, 30 Jun 2002 04:06:08 GMT
Raw View
A long time ago, I used an object-oriented Pascal compiler from Borland that
had a very nice language feature: the "parent" keyword. For example, imagine
the two classes:

class A
{
    virtual void foo() { cout << "A::foo()\n"; }
};

class B : public A
{
    virtual void foo() { A::foo(); cout << "B::foo()\n"; }
};

Now imagine that a new class, C, is created and the inheritance of class B
is modified as follows:

class A
{
    virtual void foo() { cout << "A::foo()\n"; }
};

class C : public A
{
    virtual void foo() { A::foo(); cout << "C::foo()\n"; }
};

class B : public C
{
    virtual void foo() { A::foo(); cout << "B::foo()\n"; }
};

Notice that a bug has been introduced here. The original intention of
B::foo() was to first call the base implementation A::foo() and then add
some functionality. With the insertion of class C into the inheritance
hierarchy, class B is now "broken" because it no longer invokes the base
implementation, e.g., it "skips" the base implementation of C::foo() and
continues to call directly to the base implementation provided by A::foo().
For example, the program:

void main()
{
    B b;
    b.foo();
}

outputs:

    A::foo()
    B::foo()

instead of:

    A::foo()
    C::foo()
    B::foo()

Of course, method B::foo() can be modified as follows:

class B : public C
{
    virtual void foo() { C::foo(); cout << "B::foo()\n"; }
};

in which case the output of the sample program would be:

    A::foo()
    C::foo()
    B::foo()

But my experience has been that making such modifications in large class
libraries can be very cumbersome and error-prone. Indeed it has caused some
very difficult bugs in large C++ class libraries I've supported.

The "parent" keyword solved this problem. Using this keyword, the
introduction of the thrid class, C, would would have been trivial. For
example, assume class B had originally been written using the "parent"
keyword:

class A
{
    virtual void foo() { cout << "A::foo()\n"; }
};

class B : public A
{
    virtual void foo() { parent::foo(); cout << "B::foo()\n"; }
};

The output of the sample program would be:

    A::foo()
    B::foo()

Now, adding class C is trivial:

class A
{
    virtual void foo() { cout << "A::foo()\n"; }
};

class C : public A
{
    virtual void foo() { parent::foo(); cout << "C::foo()\n"; }
};

class B : public C
{
    virtual void foo() { parent::foo(); cout << "B::foo()\n"; }
};

and the output of the sample program is:

    A::foo()
    C::foo()
    B::foo()

Sincerely,

Nate Hayes



---
[ 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: "d.hope" <dhope@all.com>
Date: Sun, 30 Jun 2002 16:36:07 GMT
Raw View
"Nate Hayes" <nhayes@sunfishstudio.com> schreef in bericht
news:uhsofqj21p3b9a@corp.supernews.com...

<snip>

> The "parent" keyword solved this problem.

What would the meaning of using the keyword parent be if a class makes use
of multiple inheritance?

---
[ 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: Dietmar Kuehl <dietmar_kuehl@phaidros.com>
Date: Sun, 30 Jun 2002 16:37:05 GMT
Raw View
Nate Hayes wrote:
[lengthy description of a feature providing access to a class' base class]

Assuming this feature is indeed useful, what should 'parent' be in this
case?

  struct A { void f() { std::cout << "A::f()\n"; } };
  struct B { void f() { std::cout << "B::f()\n"; } };
  struct C: A, B { void f() { parent::f(); std::cout << "C::f()\n"; } };

Is the specification of what 'parent' should mean in this case better than
using?

  struct C: A, B {
    typedef A parent;
    void f() { parent::f(); std::cout << "C::f()\n"; }
  };

Couldn't such a typedef solve the problem without the introduction of a
new keyword (whether it is "parent", "super", "base", or whatever names
were used in similar proposals...)?
--
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.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: "Stephen Howe" <NOSPAMsjhowe@dial.pipex.com>
Date: Mon, 1 Jul 2002 16:54:14 GMT
Raw View
"Nate Hayes" <nhayes@sunfishstudio.com> wrote in message
news:uhsofqj21p3b9a@corp.supernews.com...
>
> A long time ago, I used an object-oriented Pascal compiler from Borland
that
> had a very nice language feature: the "parent" keyword.

Rather like "super" keyword in Java.

And with

class F : public E, public D, public C, public B, public A
{
    // other details
}

which class is referred to if you use "parent" in one of F's methods?

Stephen Howe



---
[ 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: Hyman Rosen <hyrosen@mail.com>
Date: Mon, 1 Jul 2002 16:54:55 GMT
Raw View
Dietmar Kuehl wrote:
> Couldn't such a typedef solve the problem

"parent" is most useful in cases of multiple inheritance when
only one base class defines has an ancestor function, but for
different functions there are different ancestor classes -

struct A { virtual void a() { } };
struct B { virtual void b() { } };
struct C : A, B {
 void a() { parent::a(); }
 void b() { parent::b(); }
};

When there is more than one such ancestor, the compiler will
complain about ambiguity, and then you can specify one explicitly.

---
[ 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: kgwzamboni-news@zambonistiscan.com
Date: Mon, 1 Jul 2002 16:57:44 GMT
Raw View
This subject seems to keep coming up.
Why?
Something still must be typed!
If I am unfamilar with the class,
I have no idea what parent (super ... ) refers to
without going back and looking it up.
I would much rather have the base class name right there.
The only convenience seems to be to the language implimentor.



--
Remove zamboni to reply.
All the above is hearsay and the not quaranteed.

---
[ 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: Mon, 1 Jul 2002 17:25:55 GMT
Raw View
Dietmar Kuehl <dietmar_kuehl@phaidros.com> wrote in message
news:<afn27b$fh468$1@ID-86292.news.dfncis.de>...

> [lengthy description of a feature providing access to a class' base
  class]

> Assuming this feature is indeed useful, what should 'parent' be in this
> case?

>   struct A { void f() { std::cout << "A::f()\n"; } };
>   struct B { void f() { std::cout << "B::f()\n"; } };
>   struct C: A, B { void f() { parent::f(); std::cout << "C::f()\n"; } };

> Is the specification of what 'parent' should mean in this case
> better than using?

>   struct C: A, B {
>     typedef A parent;
>     void f() { parent::f(); std::cout << "C::f()\n"; }
>   };

> Couldn't such a typedef solve the problem without the introduction
> of a new keyword (whether it is "parent", "super", "base", or
> whatever names were used in similar proposals...)?

Actually, I think the reverse is true.  We don't need "super" for the
normal case, because it can easily be simulated by a typedef.  It
becomes interesting when more complex hierarchies are involved; the
effect is simply to mask the declaration in the current class, and
resolve the lookup as if this declaration wasn't there.  You no longer
have to know which base class provides the definition.

This means, of course, that it may be ambiguous.

--
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: Sungbom Kim <musiphil@bawi.org>
Date: Mon, 1 Jul 2002 22:11:45 GMT
Raw View
Nate Hayes wrote:
>
> But my experience has been that making such modifications in large class
> libraries can be very cumbersome and error-prone. Indeed it has caused some
> very difficult bugs in large C++ class libraries I've supported.
>
> The "parent" keyword solved this problem. Using this keyword, the
> introduction of the thrid class, C, would would have been trivial.

What would you say in the case of multiple inheritance?

--
Sungbom Kim <musiphil@bawi.org>

---
[ 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                       ]