Topic: Language extension
Author: gbush@my-dejanews.com
Date: 1999/05/10 Raw View
In article <7gmb97$u3r$1@proxy.st-georgen.gft.de>,
"Joerg Schaible" <Joerg.Schaible.A@T.gft.de> wrote:
> Hello,
>
> maintaining a large C++ library sometimes a bug is introduced because
of the
> missing language feature: Referring a inherited method.
Yes, it's a good concept. It's excellently implemented in Pascal. Where
inherited not just typedef to the base class, but can also be used to
invoke base class constructors in derived class constructor. Sometimes
it's desirable to make certain operations before the base constructor
is invoked. Following Pascal rules you could write:
A::A()
{
// do some operations
inherited B(); // call constructor of base class
};
but in C++ you must cram everything in initialization list. Moreover
limiting constructor names to the same as class makes this even uglier.
Gene.
--== Sent via Deja.com http://www.deja.com/ ==--
---Share what you know. Learn what you don't.---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gargantua Blargg <blargg@flash.net>
Date: 1999/05/13 Raw View
In article <7h706a$8t4@abyss.West.Sun.COM>, stanley@west.sun.com (Stanley
Friesen [Contractor]) wrote:
> In article <7gslem$cfv1@interserv.etn.com>,
> Ed Brey <brey@afd.mke.etn.com> wrote:
> >Joerg Schaible <Joerg.Schaible.A@T.gft.de> wrote in message
> >news:7gmb97$u3r$1@proxy.st-georgen.gft.de...
> >> What do you think?
> >[ about an 'inherited' keyword in C++ ]
> >
> >Java has such a keyword, called 'super' in that language. 'super' works
> >well in Java since Java doesn't support multiple inheritance, which is the
> >problem with having an 'inherited' keyword in C++.
>
> It ia amazing that this idea that multiple inheritance causes problems with
> an "inherited/super" feature is so persistent.
>
> The solution is very simple, and is in fact *already* *there* in the
> language. Check out the rules for looking up a name in super classes
> that when it not found in the current class. Now, consider defining
> "inherited" to mean "look up name as if it is not found in the current class.
> Problem solved. [Yes, *some* name lookups can end up being ambiguous - put
> that is *already* true with MI, so why should it be a worse problem when
> using an "inherited" feature???]
> >
> >The keyword 'inherited' could be defined C++ with the stipulation that it is
> >allowed only in classes that inherit from exactly one base class.
>
> Not at all. The definition I specify above is quite adequate, and makes no
> such restriction.
Yeah, my usual reply on is issue (struct used for simplicity):
struct A {
void in_a_only();
void in_both();
};
struct B {
void in_both();
void in_b_only();
};
struct derived_ : A, B { };
struct derived : derived_
{
typedef derived_ inherited;
void foo()
{
inherited::in_a_only(); // OK
inherited::in_b_only(); // OK
inherited::in_both(); // ambiguous
}
};
A real built-in keyword would behave in this manner. Currently you can do
as above.
--
"I don't like my edges rounded off" - Ani DiFranco
Gargantua Blargg | blargg@flash.net | http://www.flash.net/~blargg/
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stanley@west.sun.com (Stanley Friesen [Contractor])
Date: 1999/05/10 Raw View
In article <7gslem$cfv1@interserv.etn.com>,
Ed Brey <brey@afd.mke.etn.com> wrote:
>Joerg Schaible <Joerg.Schaible.A@T.gft.de> wrote in message
>news:7gmb97$u3r$1@proxy.st-georgen.gft.de...
>> What do you think?
>[ about an 'inherited' keyword in C++ ]
>
>Java has such a keyword, called 'super' in that language. 'super' works
>well in Java since Java doesn't support multiple inheritance, which is the
>problem with having an 'inherited' keyword in C++.
It ia amazing that this idea that multiple inheritance causes problems with
an "inherited/super" feature is so persistent.
The solution is very simple, and is in fact *already* *there* in the
language. Check out the rules for looking up a name in super classes
that when it not found in the current class. Now, consider defining
"inherited" to mean "look up name as if it is not found in the current class.
Problem solved. [Yes, *some* name lookups can end up being ambiguous - put
that is *already* true with MI, so why should it be a worse problem when
using an "inherited" feature???]
>
>The keyword 'inherited' could be defined C++ with the stipulation that it is
>allowed only in classes that inherit from exactly one base class.
Not at all. The definition I specify above is quite adequate, and makes no
such restriction.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stanley@west.sun.com (Stanley Friesen [Contractor])
Date: 1999/05/10 Raw View
In article <sfn1zklzqn.fsf@bstde026.bbn.hp.com>,
Jens Kilian <Jens_Kilian@bbn.hp.com> wrote:
>The same behavior can be achieved by a simple typedef:
>
> class Base { ... };
>
> class Derived : public Base
> {
> typedef Base inherited;
This does NOT produce the same behavior in the case of multiple inheritance,
which is where it is most useful.
class BaseA { public: int foo; ... };
class BaseB { public: int bar; ...};
class Derived: public BaseA, public BaseB {
public:
int foo;
int bar;
...
};
Now with the language extension, "inherited::foo" refers to Base::foo,
and "inherited::bar" refers to BaseB::bar. Try to do THAT with a single
typedef!!
> public:
> ...
> };
>
>Keeping the 'inherited' typedef private ensures that you don't use an
>inherited version of 'inherited':
And *this* problem is also fixed by making it a language extension rather
that a typedef.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Marc Ferry <marc@netmansys.fr>
Date: 1999/05/10 Raw View
Bruce Visscher wrote:
>
> This is discussed in 13.7 of Design and Evolution of C++ (Bjarne
> Stroustrup).
... which is an excellent book !
And in both cases (new feature or typedefs) there is an ambiguity
when used within multiple inherited classes.
Marc
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michael Podolsky <michael_podolsky@my-dejanews.com>
Date: 1999/05/09 Raw View
"Joerg Schaible" <Joerg.Schaible.A@T.gft.de> wrote:
>
> A language extension would be necessary in conjunction with multiple
> inheritance. For single inheritance, you may use this idiom.
>
Well, the next work arround will almost be suitable
for multiple inheritance
template <class Derived> class ConstructStuff;
class A{ public: A(X x); void f(); };
class B{ public: B(Y y);void g(); };
// there was class C : A,B{...};
// now -
class C;
class ConstructStuff<C> : public A, public B // service class
{
protected:
ConstructStuff(X x, Y y) : A(x), B(y) {} // Sorry, we need to
// construct this way now
};
class C: ConstructStuff<C> {typedef ConstructStuff<C> Inherited; // here we
are C(X x, Y y) : Inherited(x,y) {} // Sorry, we need to construct this way
now void t(){ Inherited::f(); Inherited::g(); } };
Surely, this is still not-perfect as you can't easily inherit
: public A, private B
Michael
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Biju Thomas <b_thomas@ibm.net>
Date: 1999/05/05 Raw View
Dave Abrahams wrote:
>
> In article <7gmb97$u3r$1@proxy.st-georgen.gft.de> , "Joerg Schaible"
> <Joerg.Schaible.A@T.gft.de> wrote:
>
> > What do you think?
>
[ about an 'inherited' keyword in C++ ]
>
> This usually isn't due to a missing language feature, but to poor library
> design. Try designing your classes so that it is never neccessary to call an
> inherited function. Use hook functions instead:
>
> class A
> {
> public:
> void callAlways() { hook(); cout << "A" << endl; }
> private:
> virtual void hook() {}
> };
>
> class B : public A
> {
> private:
> virtual void hook()
> {
> cout << "B" << endl;
> }
> };
>
> See "Taligent's Guide to Designing Programs; Well-Mannered Object-Oriented
> Design in C++" for more info.
I haven't read this book, so, this is the first time I am seeing such an
advice. Is the above guideline a practical one? Let's see.
I am deriving another class from B, called C, where I want to override
this 'hook'. The above guideline doesn't allow me to call base class
(class B) 'hook' function in this overriden 'hook' method. (Moreover, it
is private.) So, I provide another hook, 'hook2' in the most base class
(class A):
class A {
void callAlways ()
{
hook();
hook2();
}
private:
virtual void hook () {}
virtual void hook2 () {}
};
class B : public A {
private:
virtual void hook ()
{
cout << "B" << endl;
}
};
class C : public B {
private:
virtual void hook2 ()
{
cout << "C" << endl;
}
};
Now, a user wants to override the method 'callAlways' of 'C'. So, he
derives a new class from 'C'. He will ask me to add a 'hook3' virtual
member in class 'A'.
I have to update the base class 'A' whenever a user wants to enhance the
library.
So, it looks like this guideline is neither object-oriented nor
well-mannered if what we want is reuse by inheritance. Or, am I
misunderstanding this whole stuff?
Since there is no 'inherited' keyword, this is what I use (based on
Stroustrup's D&E):
class Base{};
class Derived : public Base {
typedef Base Inherited;
....
};
I use the uppercase 'Inherited' just to be safe if an 'inherited'
keyword is ever added to the language.
--
Biju 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michael Podolsky <michael_podolsky@my-dejanews.com>
Date: 1999/05/06 Raw View
Here is some way to cope with problem:
(note that base class constructor is referenced
with typedef'ed name - this compiles on VC, i am not
aware if it is ANSI-complient)
class A{};
class B: public A
{ typedef A Inherited;
B() : Inherited(){/*...*/} // trick: checks (for non-virtual inheritance)
// that Inherited is direct base
};
And i use name 'Inherited' and not 'inherited' as i'm waiting
that the last will be made a keyword some day.
Mike.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Dave Abrahams" <abrahams@mediaone.net>
Date: 1999/05/06 Raw View
In article <37308FD1.67C647B@ibm.net> , Biju Thomas <b_thomas@ibm.net>
wrote:
> Now, a user wants to override the method 'callAlways' of 'C'. So, he
> derives a new class from 'C'. He will ask me to add a 'hook3' virtual
> member in class 'A'.
>
> I have to update the base class 'A' whenever a user wants to enhance the
> library.
>
> So, it looks like this guideline is neither object-oriented nor
> well-mannered if what we want is reuse by inheritance. Or, am I
> misunderstanding this whole stuff?
I think you might be a little bit. In practice it is usually possible to
anticipate the places and ways in which client sub-classes may need to
override behaviors. If you can do this you remove the question of when (or
if) the base class implementation needs to be called. Also, it helps to
insulate client subclasses from the parent class' implementation. It takes
some thinking about your designs, though.
In a particular case that the original poster mentioned (writing streaming
operators) things are a bit more complicated because in general one must
always _extend_ the functionality of the base class in the derived class.
Although this is an unusual case it is possible (with some work) to follow
the guideline here, too, without incurring changes in the base class for
each new derived class.
-Dave
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ed Brey" <brey@afd.mke.etn.com>
Date: 1999/05/07 Raw View
Joerg Schaible <Joerg.Schaible.A@T.gft.de> wrote in message
news:7gmb97$u3r$1@proxy.st-georgen.gft.de...
> What do you think?
[ about an 'inherited' keyword in C++ ]
Java has such a keyword, called 'super' in that language. 'super' works
well in Java since Java doesn't support multiple inheritance, which is the
problem with having an 'inherited' keyword in C++.
The keyword 'inherited' could be defined C++ with the stipulation that it is
allowed only in classes that inherit from exactly one base class. However,
this kind of special-case stipulation has problems. One is that it
increases the complexity of the language. Another is that the adding a
second base class to an existing derived class becomes more likely to break
the derived class. As C++ exists now, adding an additional base class
generally doesn't break any existing code (assuming you are multiply
inheriting for a good reason).
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jens Kilian <Jens_Kilian@bbn.hp.com>
Date: 1999/05/07 Raw View
"Joerg Schaible" <Joerg.Schaible.A@T.gft.de> writes:
> Unless inherited::<method> is not ambigous it should be possible to call
> inherited functions without an explicit qualified name. Introducing the new
> class BBase, the method BBase::callAlways would have been called
> automatically.
The same behavior can be achieved by a simple typedef:
class Base { ... };
class Derived : public Base
{
typedef Base inherited;
public:
...
};
Keeping the 'inherited' typedef private ensures that you don't use an
inherited version of 'inherited':
class MoreDerived : public Derived
{
// Forgot to define 'inherited'
public:
MoreDerived(int passToParentConstructor)
: inherited(passToParentConstructor) // error
{
...
}
...
};
Regards,
Jens.
--
mailto:jjk@acm.org phone:+49-7031-14-7698 (HP TELNET 778-7698)
http://www.bawue.de/~jjk/ fax:+49-7031-14-7351
PGP: 06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Bruce Visscher <bvisscher@mindspring.com>
Date: 1999/05/07 Raw View
Joerg Schaible wrote:
>
> Unless inherited::<method> is not ambigous it should be possible to call
> inherited functions without an explicit qualified name. Introducing the new
> class BBase, the method BBase::callAlways would have been called
> automatically.
>
> What do you think?
No flame intended, but I think this has to be the most frequently offered
language extension in this group and in clcm.
This is discussed in 13.7 of Design and Evolution of C++ (Bjarne Stroustrup).
The reason it wasn't added is because you can solve the problem yourself:
class B : public A {
public:
typedef A inherited;
//
};
Hmm, it does seem slightly more error prone than if the language had provided
this. Also, I wonder if it might have been less effort to have added it than to
have to repeatedly explain why it wasn't added:-). (Note: I don't have a strong
preference one way or the other.)
Bruce
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Joerg Schaible" <Joerg.Schaible.A@T.gft.de>
Date: 1999/05/07 Raw View
>And i use name 'Inherited' and not 'inherited' as i'm waiting
>that the last will be made a keyword some day.
A language extension would be necessary in conjunction with multiple
inheritance. For single inheritance, you may use this idiom.
Greetings, J rg
--
BTW: It is normally better to answer to the group! For direct mail reply
exchange the ".A@T." by "@"
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/05/07 Raw View
Ed Brey wrote:
> Java has such a keyword, called 'super' in that language. 'super' works
> well in Java since Java doesn't support multiple inheritance, which is the
> problem with having an 'inherited' keyword in C++.
Once again, MI is an argument *for* inherited, not against.
It makes it more usefull. (See my other post in this thread.)
--
Valentin Bonnard
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Joerg Schaible" <Joerg.Schaible.A@T.gft.de>
Date: 1999/05/04 Raw View
Hello,
maintaining a large C++ library sometimes a bug is introduced because of the
missing language feature: Referring a inherited method. See following
example:
class A
{
public:
virtual void callAlways() { cout << "A" << endl; }
};
class B : public A
{
public:
virtual void callAlways()
{
cout << "B" << endl;
A::callAlways();
}
};
This idiom is normally used for isOfType or streaming functionality.
Maintaining code (or continue developing), you will have to introduce an
additional base class to generalize some functionality and your code may
look like:
class A
{
public:
virtual void callAlways() { cout << "A" << endl; }
};
class BBase : public A
{
public:
virtual void callAlways()
{
cout << "BBase" << endl;
A::callAlways();
}
};
class B : public BBase
{
public:
virtual void callAlways()
{
cout << "B" << endl;
A::callAlways(); // <===== wrong now!
}
};
===> and typically you don't know, won't remember or forget the reference of
A::callAlways in class B.
This could have been prevented by a key word "inherited" in the original
source:
class A
{
public:
virtual void callAlways() { cout << "A" << endl; }
};
class B : public A
{
public:
virtual void callAlways()
{
cout << "B" << endl;
inherited::callAlways(); // <===== here
}
};
Unless inherited::<method> is not ambigous it should be possible to call
inherited functions without an explicit qualified name. Introducing the new
class BBase, the method BBase::callAlways would have been called
automatically.
What do you think?
Greetings, Jvrg
--
BTW: It is normally better to answer to the group! For direct mail reply
exchange the ".A@T." by "@"
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Dave Abrahams" <abrahams@mediaone.net>
Date: 1999/05/05 Raw View
In article <7gmb97$u3r$1@proxy.st-georgen.gft.de> , "Joerg Schaible"
<Joerg.Schaible.A@T.gft.de> wrote:
> What do you think?
This usually isn't due to a missing language feature, but to poor library
design. Try designing your classes so that it is never neccessary to call an
inherited function. Use hook functions instead:
class A
{
public:
void callAlways() { hook(); cout << "A" << endl; }
private:
virtual void hook() {}
};
class B : public A
{
private:
virtual void hook()
{
cout << "B" << endl;
}
};
See "Taligent's Guide to Designing Programs; Well-Mannered Object-Oriented
Design in C++" for more info.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]