Topic: Proposal: Unamed Base Class Member Access
Author: Andrew Gierth <andrewg@microlise.co.uk>
Date: 1996/08/29 Raw View
>>>>> "Rob" == Rob Stewart <stew@datalytics.com> writes:
Rob> Has anyone ever thought of adding some means of accessing
Rob> base class members without having to explicitly name the base
Rob> class? [ker-snip]
If I recall my D&E correctly (don't have it handy), it was proposed, but
dropped when someone pointed out that
class Foo : public Bar
{
public:
typedef Bar Base;
...
};
has roughly the desired effect (at the cost of adding one trivial
declaration per class). Some class frameworks (e.g. IBM's) use this
pattern.
--
Andrew Gierth (andrewg@microlise.co.uk)
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: sj@aracnet.com (Scott Johnson)
Date: 1996/08/29 Raw View
In article <199608282133.OAA02629@taumet.eng.sun.com>,
Steve Clamage <clamage@taumet.Eng.Sun.COM> wrote:
>In article j9l@grotto.datalytics.com, stew@datalytics.com (Rob Stewart) writes:
>>Has anyone ever thought of adding some means of accessing
>>base class members without having to explicitly name the base
>>class? For example, the assignment operator must call the base
>>class' assignment operator. To do so requires scope resolution
>>(assume Derived is derived from Base): ...
>>
>This is a variation on the frequently-proposed "parent" or "super"
>keyword, which would refer to the immediate base class.
>
>The reasons for not including such a keyword (and whether you spell
>the keyword "parent" or "super" or "^" isn't very important)
>are discussed in D&E.
>
>Briefly, you can get the effect you want with a typedef:
[...]
>Inside any derived class you can refer to Parent. You have only one
>typedef to change if you change the base-list in the declaration, and
>the typedef is located on the line right after the base-list.
>
>A problem with the special keyword is, as you noted, what happens
>when there is more than one base class. The trend in real-world
>applications is for multiple inheritance to be the norm, rather than
>the exception. A solution that doesn't address MI doesn't seem worth
>adding to the language.
>
>Not everyone agrees with this analysis.
Use of typedef, obviously, doesn't deal with multiple inheritence (unless
you explicitly WANT to only consider one class the "parent" class.
Sometimes this crops up.)
If a "parent" or "super" keyword WAS used, it could be used with MI, as
follows:
Use of parent::X, where X is any sort of member of one of the parents,
will "pick out" which parent has a member called X, and use that parent's
X. If no parent has X, it's obviously an error; if multiple parents have
an X, this is an error as well. (Unless, possibly, all but one of the Xs
are private to the parent classes.....)
I'm still not sure if this would be useful; but it would be compatible
with MI.
Scott
--
/--------------------------------------------------------------------------\
|Scott Johnson -- Professional (sometimes) SW Engineer and all-purpose Geek|
|I don't speak for nobody but myself, which everyone else is thankful for |
\--------------------------------------------------------------------------/
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: jason@cygnus.com (Jason Merrill)
Date: 1996/08/29 Raw View
>>>>> Steve Clamage <clamage@taumet.Eng.Sun.COM> writes:
> A problem with the special keyword is, as you noted, what happens
> when there is more than one base class. The trend in real-world
> applications is for multiple inheritance to be the norm, rather than
> the exception. A solution that doesn't address MI doesn't seem worth
> adding to the language.
> Not everyone agrees with this analysis.
Me, for example. I would expect the special keyword to mean "lookup as
though there is no declaration in this class", and thus work better than an
explicit typedef, which only works with a single base.
But then, I don't really care.
Jason
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1996/08/29 Raw View
Rob Stewart writes:
> Has anyone ever thought of adding some means of accessing
> base class members without having to explicitly name the base
> class? For example, the assignment operator must call the base
> class' assignment operator. To do so requires scope resolution
> (assume Derived is derived from Base):
What about:
class Derived : public Base {
private:
typedef Base mybase;
//...
public:
Derived& Derived::operator =(
const Derived& i_Other)
{
if (&i_Other != this)
{
mybase::operator =(i_Other); // scope resolved
// assign Derived's dms here
}
return *this;
}
};
This can even take care of multiple inheritance --- there can be
several typedefs. However, the "problem" of being unable to
initialize base-classes in the constructor using these alternate names
persists.
--
Alexandre Oliva
oliva@dcc.unicamp.br
Universidade Estadual de Campinas, S o Paulo, Brasil
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: stew@datalytics.com (Rob Stewart)
Date: 1996/08/29 Raw View
clamage@taumet.Eng.Sun.COM (Steve Clamage) wrote:
>In article j9l@grotto.datalytics.com, stew@datalytics.com (Rob Stewart) writes:
>>Has anyone ever thought of adding some means of accessing
>>base class members without having to explicitly name the base
>>class? For example, the assignment operator must call the base
>>class' assignment operator. To do so requires scope resolution
>>(assume Derived is derived from Base): ...
>>
>>What happens if Derived's base class changes? What if you
>>introduce a new, intervening, base class between Base and
>>Derived? You have to find all scope resolutions to the base class
>>to change the class name. Sure this is just a search and replace
>>in the header and implementation files. But you could eliminate
>>the dependency on the immediate, SI, base class name with
>>something like this:
>>
>> ^::operator =(i_Other);
>>
>This is a variation on the frequently-proposed "parent" or "super"
>keyword, which would refer to the immediate base class.
I didn't want to introduce another keyword that would cause
problems with identifiers. However, I see that I'm pretty late to
this game.
>The reasons for not including such a keyword (and whether you spell
>the keyword "parent" or "super" or "^" isn't very important)
>are discussed in D&E.
What is "D&E?"
>Briefly, you can get the effect you want with a typedef:
Something I hadn't considered.
> class Derived : public Base {
> typedef Base Parent;
> ... // remainder of class
> };
> class MoreDerived : public Derived {
> typedef Derived Parent;
> ... // remainder of class
> };
>
>Inside any derived class you can refer to Parent. You have only one
>typedef to change if you change the base-list in the declaration, and
>the typedef is located on the line right after the base-list.
That's good. It keeps the typedef right next to the parent
declaration, so maintenance is easier.
>A problem with the special keyword is, as you noted, what happens
>when there is more than one base class. The trend in real-world
>applications is for multiple inheritance to be the norm, rather than
>the exception.
Gee, I guess our apps aren't "real world." We generally avoid MI.
>A solution that doesn't address MI doesn't seem worth
>adding to the language.
OTOH, even the typedef, as presented, doesn't address MI; you'd
have to have multiple typedefs, and even these would be
problematic. Do you call them "LeftParent" and "RightParent?"
What about "MiddleParent" or "LeftOfMiddleParent?" And what
happens when the order of the bases changes? You simply can't do
it generically for MI. (You could name them such that
the names are indicative of the purpose of each base,
but that can prove difficult to manage.) Therefore, the MI case
doesn't seem important in considering whether to include this
feature in the language.
Of course the typedef idea has additional merit. You can use it
in ctor-initializers and it would adjust the code automatically
when the base class changes (assuming the new base class uses the
same parameter list as the previous one).
Robert Stewart | My opinions are usually my own.
Datalytics, Inc. | stew@datalytics.com
| http://www.datalytics.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: 100653.2230@compuserve.com (Raoul De Kezel)
Date: 1996/08/31 Raw View
stew@datalytics.com (Rob Stewart) wrote:
>OTOH, even the typedef, as presented, doesn't address MI; you'd
>have to have multiple typedefs, and even these would be
>problematic. Do you call them "LeftParent" and "RightParent?"
[snip]
>(You could name them such that
>the names are indicative of the purpose of each base,
>but that can prove difficult to manage.
In practice it works very well. When I need to use the public or
protected base interface X in a derived class, I use the typedef
SuperX, and I don't remember having ever had any trouble.
eg
class Window ... ;
class Laidout ... ;
class LaidoutWindow : public virtual Window,
public virtual Laidout
{
typedef Window SuperWindow;
typedef Laidout SuperLaidout;
...
};
class AnotherWindow : public virtual LaidoutWindow
{
...
};
class StillAnotherWindow : public virtual AnotherWindow
{
// Either
typedef AnotherWindow SuperWindow;
typedef AnotherWindow SuperLaidout;
// Or - if LaidoutWindow was promoted to an interface -
typedef AnotherWindow SuperLaidoutWindow;
};
--- Raoul
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: stew@datalytics.com (Rob Stewart)
Date: 1996/08/28 Raw View
Has anyone ever thought of adding some means of accessing
base class members without having to explicitly name the base
class? For example, the assignment operator must call the base
class' assignment operator. To do so requires scope resolution
(assume Derived is derived from Base):
Derived& Derived::operator =(
const Derived& i_Other)
{
if (&i_Other != this)
{
Base::operator =(i_Other); // scope resolved
// assign Derived's dms here
}
return *this;
}
What happens if Derived's base class changes? What if you
introduce a new, intervening, base class between Base and
Derived? You have to find all scope resolutions to the base class
to change the class name. Sure this is just a search and replace
in the header and implementation files. But you could eliminate
the dependency on the immediate, SI, base class name with
something like this:
^::operator =(i_Other);
I'm suggesting the circumflex combined with the scope resolution
operator since the circumflex suggests "up" the inheritance
hierarchy, and we're still scope resolving the member access.
In the above line, this would tell the compiler to call the
immediate base class' mf.
Obviously, the compiler would have to declare an error if Derived
inherits from more than one base. In that case, you could specify
left and right bases with some other syntax. But you couldn't
handle an arbitrary number of base classes and you'd run into
problems in which the indicated class changes when the base class
declaration order changes. So, you would have to explicitly name
the base class in the presence of MI. Since MI is not nearly so
common as SI, this restriction shouldn't reduce the benefit of
this new operator much.
This operator doesn't help with ctor initializer lists having to
name the base class explicitly, but construction is a little
different anyway.
Robert Stewart | My opinions are usually my own.
Datalytics, Inc. | stew@datalytics.com
| http://www.datalytics.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: clamage@taumet.Eng.Sun.COM (Steve Clamage)
Date: 1996/08/28 Raw View
In article j9l@grotto.datalytics.com, stew@datalytics.com (Rob Stewart) writes:
>Has anyone ever thought of adding some means of accessing
>base class members without having to explicitly name the base
>class? For example, the assignment operator must call the base
>class' assignment operator. To do so requires scope resolution
>(assume Derived is derived from Base): ...
>
>What happens if Derived's base class changes? What if you
>introduce a new, intervening, base class between Base and
>Derived? You have to find all scope resolutions to the base class
>to change the class name. Sure this is just a search and replace
>in the header and implementation files. But you could eliminate
>the dependency on the immediate, SI, base class name with
>something like this:
>
> ^::operator =(i_Other);
>
>I'm suggesting the circumflex combined with the scope resolution
>operator since the circumflex suggests "up" the inheritance
>hierarchy, and we're still scope resolving the member access.
>In the above line, this would tell the compiler to call the
>immediate base class' mf. ...
This is a variation on the frequently-proposed "parent" or "super"
keyword, which would refer to the immediate base class.
The reasons for not including such a keyword (and whether you spell
the keyword "parent" or "super" or "^" isn't very important)
are discussed in D&E.
Briefly, you can get the effect you want with a typedef:
class Derived : public Base {
typedef Base Parent;
... // remainder of class
};
class MoreDerived : public Derived {
typedef Derived Parent;
... // remainder of class
};
Inside any derived class you can refer to Parent. You have only one
typedef to change if you change the base-list in the declaration, and
the typedef is located on the line right after the base-list.
A problem with the special keyword is, as you noted, what happens
when there is more than one base class. The trend in real-world
applications is for multiple inheritance to be the norm, rather than
the exception. A solution that doesn't address MI doesn't seem worth
adding to the language.
Not everyone agrees with this analysis.
---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]