[comp.lang.c++] Class scope and virtual functions

jeff1@garfield.mun.edu (Jeff Sparkes) (11/09/89)

>>>>> On 8 Nov 89 16:07:57 GMT, kdu@iris.brown.edu (Kenneth Utting) said:

kdu> In article <1989Nov7.073836.23166@brutus.cs.uiuc.edu> 
kdu> sane@brutus.cs.uiuc.edu (Aamod Sane) writes:
sane> What I mean is a parent->method() somewhat like this->method() but
sane> refering to the class from where to start lookup. 

kdu> Apple's MPW C++ for the Macintosh supports an "inherited"
kdu> keyword. So, rather than writing "between::func()" you write
kdu> "inherited::func()" I don't know how this behaves with multiple
kdu> inheritance.

kdu> Regardless of the merits of using special keywords versus
kdu> specifying the inherited class explicitly, what I find truly
kdu> astonishing is that neither of the two C++ books I have
kdu> (Stroustrup and Dewhurst & Stark) even mention this topic (how
kdu> one method can call its inherited version). It is as though the
kdu> creators and developers of this language do not think this is
kdu> something anyone would want to do (my belief, on the other hand,
kdu> is that this is one of the most fundamental operations in
kdu> object-oriented programming).

I've sometimes found it necessary to add some code in a
derived class to handle special cases, and then having to copy the
code from the original to handle the normal case.  I'd love to be able
to just handle the special case, or just call parent->method() to deal
with the normal.

--
Jeff Sparkes	jeff1@garfield.mun.edu || uunet!garfield!jeff1
Humans couldn't have invented golf without alien intervention--Kids in the Hall

bs@alice.UUCP (Bjarne Stroustrup) (11/10/89)

 > keith@csli.Stanford.EDU (Neil Hunt) writes:
 > 
 > >In article <21847@gryphon.COM> sarima@gryphon.COM (Stan Friesen) writes:
 > 
 > >>	A simplified example follows:
 > >>class base { virtual int func(); };
 > >>class between: public base { // no redef of func(), so use base::func() };
 > >>class derived: public between { int func(); };
 > >>int derived::func() {
 > >>	between::func();		// I think this is illegal
 > >>}

 > >This is certainly permitted in AT&T cfront 1.2; I have used it in
 > >several cases.
 > >It is certainly desirable.
 > >If it went away in 2.0, that seems like a bug to me!

It works - as always. The only thing I see wrong with the (condenced) example
is the misuse ofthe // in the second line and the fact  that base::func() is
private. Fixing that I get this:

class base { virtual int func(); };
class between: public base { // no redef of func(), so use base::func() };
class derived: public between { int func(); };
int derived::func() {
	between::func();		// I think this is illegal
}

which compiles just fine.

horstman@sjsumcs.sjsu.edu (Cay Horstmann) (11/11/89)

Several people asked for the possibility of calling

	super->f()

to invoke the method f() in the immediate superclass. I don't see why
that would be such a wonderful feature. YOU built the inheritance tree,
so you know the name of the superclass and can invoke it with

	superclassname::f()

(And, in the case of multiple inheritance, you'd have to specify anyway
which superclass you wanted to defer to.) 

The only time when you don't know the name of the superclass is when the
code of your function is generated by a macro. Did anyone ever run into
a situation in which such a macro might be useful?

sarima@gryphon.COM (Stan Friesen) (11/13/89)

In article <20130@brunix.UUCP> kdu@iris.brown.edu (Kenneth Utting) writes:
>
>Regardless of the merits of using special keywords versus specifying the
>inherited class explicitly, what I find truly astonishing is that neither
>of the two C++ books I have (Stroustrup and Dewhurst & Stark) even mention
>this topic (how one method can call its inherited version). It is as though 
>the creators and developers of this language do not think this is something
>anyone would want to do (my belief, on the other hand, is that this is one
>of the most fundamental operations in object-oriented programming).
>
	This is why I posted the question.  Lippman's book does not mention
it either.  His book does discuss scope resolution though, and it seems to
imply that between::func() requires an explicit instance of func() in the
intermediate class.  At least two people have said that my example actually
works (one by email).   I like the idea of inherited::func() even better.
I hope that my approach is at least officially sanctioned so it won't go
away suddenly (unless 'inherited' is added).
-- 
Sarima Cardolandion			sarima@gryphon.CTS.COM
aka Stanley Friesen			rutgers!marque!gryphon!sarima
					Sherman Oaks, CA

dlw@odi.com (Dan Weinreb) (11/13/89)

In article <1989Nov11.033053.4148@sjsumcs.sjsu.edu> horstman@sjsumcs.sjsu.edu (Cay Horstmann) writes:


   Several people asked for the possibility of calling

	   super->f()

   to invoke the method f() in the immediate superclass. I don't see why
   that would be such a wonderful feature. YOU built the inheritance tree,
   so you know the name of the superclass and can invoke it with

Becuase sometimes you do NOT build the inheritance tree!

Suppose George writes a class called borders_mixin.  Nobody is ever
intended to instantiate this class.  George installs it in a library
of reusable component classes.  He advertises that if you are making
your own window class, and you'd like your window to have borders, all
you need to do is inherit from borders_mixin, and, voila, nice
borders.

Now Martha wants to make a particular window class.  She looks through
all the libraries, and discovers some nice goodies, including George's
borders_mixin, as well as Fred's label_mixin and Laura's
pulldown_bar_mixin.  She makes her new class inherit from all three of
those, in no particular order, since they're really orthogonal
features.  So Martha determined the order, not George.

Now, each "mixin" class might want to handle the "redraw yourself"
virtual function, by redrawing its own contribution, and then passing
on control to the next class down the line.  This is what the CLOS
"call-next-method" function is for, and this is what "super->f()" is
essentially for (except that "super" is a somewhat poor name in the
presence of multiple inheritance).

There are scenarios involving only single inheritance that answer your
question (as earlier postings pointed out), but I think the multiple
inheritance scenario makes a more powerful case for the benefits of
method combination.

These concepts are explained at greater length and with greater
clarity in an excellent book: "Object-Oriented Programming in Common
Lisp" by Sonya Keene.  Even if you're a C++ programmer and are only
somewhat familiar with Lisp, you shouldn't have much trouble following
the book's explanation of what multiple inheritance is good for, and
how to use it in the manner in which I describe above.

Dan Weinreb		Object Design, Inc.		dlw@odi.com

bs@alice.UUCP (Bjarne Stroustrup) (11/13/89)

`baseclassname::f()' calls the function `f' declared in `baseclassname' or
one of its base classes. The call is checked for ambiguity of `f' in
`baseclassname'.

As noted, the most common use of this is to call a function f() from a
base class from a function f() in a derived class.


This was always so. It will remain so. I will make sure that the reference
manual is precise and explicit about this.

I guess that the most obvious facts are also the easierst ones to forget to
mention. Sorry.

The `inherited::f()' idea works only for single inheritance - that was why is
wasn't used. It seems that this notation can be added to C++ with multiple
inheritance without much trouble but that does not in itself prove that it
ought to be added. We'll see.