Topic: Proposal: empty base classes disambiguated
Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 2000/02/24 Raw View
Hyman Rosen <hymie@prolifics.com> wrote:
: "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
:> But now I realize that anyway my proposal can break existing code. I'm
:> curious to find information in depth about the Java object model. There,
:> interfaces are prohibited from holding data members and I feel the absence
:> of data members makes for an important difference. This difference could be
:> exploited automatically by a C++ compiler.
: The Java interface model is (almost) entirely equivalent to C++
: virtual abstract base classes without data members. That is, if
: in Java you write 'class C implements I', in C++ you would write
: 'class C : public virtual I'.
: The almost is because Java lets you inherit interface implementations
: from base classes, and C++ does not. That is, in Java you can write -
: class M { public void f() { } }
: interface I { void f(); }
: class F extends M implements I { } // F.M.f() satisfies F.I.f()
: whereas in C++ you must forward -
: struct M { void f() { } };
: struct I { virtual void f() = 0; }
: struct F : M, virtual I { void f() { M::f(); } };
No, you don't have to forward. F::M::f() qualifies as the
"final overrider" of F::I::f().
Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/02/24 Raw View
Oleg Zabluda wrote:
>
> Hyman Rosen <hymie@prolifics.com> wrote:
> : "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
> :> But now I realize that anyway my proposal can break existing code. I'm
> :> curious to find information in depth about the Java object model. There,
> :> interfaces are prohibited from holding data members and I feel the absence
> :> of data members makes for an important difference. This difference could be
> :> exploited automatically by a C++ compiler.
>
> : The Java interface model is (almost) entirely equivalent to C++
> : virtual abstract base classes without data members. That is, if
> : in Java you write 'class C implements I', in C++ you would write
> : 'class C : public virtual I'.
>
> : The almost is because Java lets you inherit interface implementations
> : from base classes, and C++ does not. That is, in Java you can write -
>
> : class M { public void f() { } }
> : interface I { void f(); }
> : class F extends M implements I { } // F.M.f() satisfies F.I.f()
>
> : whereas in C++ you must forward -
>
> : struct M { void f() { } };
> : struct I { virtual void f() = 0; }
> : struct F : M, virtual I { void f() { M::f(); } };
>
> No, you don't have to forward. F::M::f() qualifies as the
> "final overrider" of F::I::f().
No, since M::f() doesn't override I::f() at all
(because M doesn't inherit from I).
The situation where "final overriders" looks like this:
struct I { virtual void f() = 0; }
struct M: virtual I { void f() {} };
struct F: M, virtual I {};
Note the difference in M.
Here the f() inherited directly from I by F is overridden
by the f() inherited from M, since the I object M inherits
is the same one, and M overrides I::f(). Therefore F::M::f
is the final overrider.
---
[ 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: 2000/02/24 Raw View
Oleg Zabluda wrote:
> Hyman Rosen <hymie@prolifics.com> wrote: (edited by VB)
> : whereas in C++ you [should] forward -
>
> : struct M { void f() { } };
> : struct I { virtual void f() = 0; }
> : struct F : M, virtual I { };
> No, you don't have to forward. F::M::f() qualifies as the
> "final overrider" of F::I::f().
How could it be a final overrider when it isn't
even an overrider ?
The final overrider of F::M::f() is F::M::f(),
the final overrider of F::I::f() is F::I::f(),
and F is abstract (but well-formed).
--
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: Hyman Rosen <hymie@prolifics.com>
Date: 2000/02/24 Raw View
Oleg Zabluda <zabluda@math.psu.edu> writes:
> Hyman Rosen <hymie@prolifics.com> wrote:
> : whereas in C++ you must forward -
>
> : struct M { void f() { } };
> : struct I { virtual void f() = 0; }
> : struct F : M, virtual I { void f() { M::f(); } };
>
> No, you don't have to forward. F::M::f() qualifies as the
> "final overrider" of F::I::f().
It does not. Try it on your favorite compiler -
struct M { void f() { } };
struct I { virtual void f() = 0; }
struct F : M, virtual I { };
int main() { F f; f.f(); }
Read 10.3/2 *carefully*, and note that there is no overrider for F::M::f,
because no derived class of I has an f.
---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 2000/02/07 Raw View
I have a proposal that I think it's quite sensible (duh!)
Multiple inheritance from the same class is crippled by the problems that
led to virtual inheritance.
The problems with nonvirtual multiple inheritance stem from the existence of
two base subobjects in the end object. Because of this, every access to a
member of the superclass to which the two subobjects belong is ambiguous.
If the base class is empty (does not have any member variables), however,
the ambiguity problems dissapear as the two subobjects don't have
distinguishable data.
The proposal is the language to allow disambiguated diamond-MI from classes
as long as they don't have data members. This is easy to implement and
doesn't break existing programs.
In the object mopdel, the two base subobjects would have the same vtable so
access through one is the same as access through the other. This way, no
ambiguity can conceptually occur.
This is how Java interfaces are implemented, I think. I guess this proposal
has been discussed, right?
If this feature was implemented, I could define a class like below.
class Polymorphic
{
public:
Polymorphic() {}
virtual ~Polymorphic() {}
private:
Polymorphic(const Polymorphic&);
Polymorphic& operator=(const Polymorphic&);
};
This class makes the rules of polymorphic classes clear - virtual destructor
and no value semantics - and have teh compiler enforce (partially) these
rules.
I would encourage colleagues to inherit Polymorphic for polymorphic objects,
etc. The problem is, they won't be able to use multiple inheritance down the
road unless they inherit virtual from Polymorphic, and nobody wants to
inherit virtually unless they really need to. This has to do with the bad
efficiency record that virtual inheritance has.
The feature would allow such interfaces and mixins to exist - I'm not sure,
but I think one can build good mixins combining this feature with Coplien's
curiously recurring pattern.The language rules as they are now basically
don't allow reasonably good mixins.
Andrei
---
[ 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: 2000/02/07 Raw View
in article s9q1ooms98e28@news.supernews.com, Andrei Alexandrescu at
andrewalex@hotmail.com wrote on 2/7/00 10:09 AM:
> The proposal is the language to allow disambiguated diamond-MI from classes
> as long as they don't have data members. This is easy to implement and
> doesn't break existing programs.
>
> In the object mopdel, the two base subobjects would have the same vtable so
> access through one is the same as access through the other. This way, no
> ambiguity can conceptually occur.
>
> This is how Java interfaces are implemented, I think. I guess this proposal
> has been discussed, right?
Not to my knowledge, but that doesn't mean anything. Most things have been
discussed ;) This is a very interesting proposal!
---
[ 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: Ron Natalie <ron@sensor.com>
Date: 2000/02/08 Raw View
Andrei Alexandrescu wrote:
> In the object mopdel, the two base subobjects would have the same vtable so
> access through one is the same as access through the other. This way, no
> ambiguity can conceptually occur.
I wish vtables were not brought up in a description of language features, but
since you did, to do this (force the vtables to be the same) would pose the
same problems as making the classes virtual to begin with.
> If the base class is empty (does not have any member variables), however,
> the ambiguity problems dissapear as the two subobjects don't have
> distinguishable data.
>
>
I don't buy this. The memembers (even though they are functions) are
distinguisable
Consider the following empty class heirarchy:
class Base {
public:
virtual void woo() {
foo();
}
virtual void foo() = 0;
};
class Left : public Base {
public:
void foo();
};
class Right : pbulic Base {
public:
void foo();
};
class Derived : public Left, public Right {
public:
void goo() {
woo();
}
};
This program would compile under your rule, but Derived::goo calling woo() would be
ambiguous. The virtual foo () called in Base::who() would depend on which leg of the
tree you were on.
And what good would making "all" polymorphic class inherit from polymorphic? Other
than the trivial addition of the virtual destrutor, the rest does nothing. Nobody
really works with polymorphic objects with that low of a handle. The fundemental
interface is going to at least have some virtual functions or it's not really
going to be very useful. What are your copy constructor/copy assigmentment
ops going to do that's of any practical use here?
---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 2000/02/08 Raw View
Ron Natalie <ron@sensor.com> wrote in message
news:389DF686.9BB751A8@sensor.com...
> I wish vtables were not brought up in a description of language features,
but
> since you did, to do this (force the vtables to be the same) would pose
the
> same problems as making the classes virtual to begin with.
I just mentioned vtables to illustrate why the concept makes sense.
> I don't buy this. The memembers (even though they are functions) are
> distinguisable
>
> Consider the following empty class heirarchy:
>
> class Base {
> public:
> virtual void woo() {
> foo();
> }
> virtual void foo() = 0;
> };
>
> class Left : public Base {
> public:
> void foo();
> };
>
> class Right : pbulic Base {
> public:
> void foo();
> };
>
> class Derived : public Left, public Right {
> public:
> void goo() {
> woo();
> }
> };
>
> This program would compile under your rule, but Derived::goo calling woo()
would be
> ambiguous. The virtual foo () called in Base::who() would depend on which
leg of the
> tree you were on.
Nonono... let me explain.
The problem in your code is that you overrode foo() two times. It is this
fact that generates the ambiguity, not the "collapsed" inheritance. In other
words, the code above does not compile under existing rules nor my proposed
rules.
The code above does not compile even with virtual inheritance. The rule I
propose would let code that today compiles only with virtual inheritance, to
compile with nonvirtual inheritance, if the base class does not have data
members.
The rule I propose would render the two subobjects having the same address,
which is an exception to the rule that each object has a unique address. But
there was an exception with derived and base classes anyway.
> And what good would making "all" polymorphic class inherit from
polymorphic? Other
> than the trivial addition of the virtual destrutor, the rest does nothing.
Nobody
> really works with polymorphic objects with that low of a handle. The
fundemental
> interface is going to at least have some virtual functions or it's not
really
> going to be very useful. What are your copy constructor/copy
assigmentment
> ops going to do that's of any practical use here?
A lot. The Polymorphic class makes it clear that:
* the type has a virtual desctructor
* the type does not have first-class semantics
I have seen programmers repeatedly having problems with properly defining
polymorphic types. Many don't understand run-time polymorphism in C++ and
first-class (value) semantics are mutual exclusive features. Exceptions
exist, but those are cases in which you forgo the polymorphic semantics.
The Polymorphic class would be a good artifact in coding standards, a good
documentation tool, and a means to let the compiler detect unwitting abuse.
Polymorphic is not intended to be manipulated by functions per se. It is not
a functional unit, it's an enforcement means.
Andrei
---
[ 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: kanze@gabi-soft.de
Date: 2000/02/08 Raw View
"Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
|> I have a proposal that I think it's quite sensible (duh!)
|> Multiple inheritance from the same class is crippled by the problems
|> that led to virtual inheritance.
|> The problems with nonvirtual multiple inheritance stem from the
|> existence of two base subobjects in the end object. Because of this,
|> every access to a member of the superclass to which the two
|> subobjects belong is ambiguous.
|> If the base class is empty (does not have any member variables),
|> however, the ambiguity problems dissapear as the two subobjects
|> don't have distinguishable data.
What does distinguishable data have to do with the question? I'm not
too sure I understand what you are proposing, but if it is allowing
multiple instances of a base class which should be unique, it poses
problems with regards to identity. All pointers to the single base
class must compare equal, which pretty much means that there can be only
one instance.
|> The proposal is the language to allow disambiguated diamond-MI from
|> classes as long as they don't have data members. This is easy to
|> implement and doesn't break existing programs.
|> In the object mopdel, the two base subobjects would have the same
|> vtable so access through one is the same as access through the
|> other. This way, no ambiguity can conceptually occur.
|> This is how Java interfaces are implemented, I think. I guess this
|> proposal has been discussed, right?
I'm not sure how Java interfaces are implemented in detail, but the
problem is different in Java; because *only* interfaces may be
inherited, you have a priviledged branch. When comparing pointers, I
suspect that the pointer values are always cast to Object first, and
because Object is a class and not an interface, it can occur only once
in the inheritance lattice.
|> If this feature was implemented, I could define a class like below.
|> class Polymorphic
|> {
|> public:
|> Polymorphic() {}
|> virtual ~Polymorphic() {}
|> private:
|> Polymorphic(const Polymorphic&);
|> Polymorphic& operator=(const Polymorphic&);
|> };
|> This class makes the rules of polymorphic classes clear - virtual
|> destructor and no value semantics - and have the compiler enforce
|> (partially) these rules.
|> I would encourage colleagues to inherit Polymorphic for polymorphic
|> objects, etc. The problem is, they won't be able to use multiple
|> inheritance down the road unless they inherit virtual from
|> Polymorphic, and nobody wants to inherit virtually unless they
|> really need to. This has to do with the bad efficiency record that
|> virtual inheritance has.
Most of the bad record concerns space, not time, and is due to an error
in C-Front. I've worked on a lot of applications where virtual
inheritance was the rule, and it has never caused problems with any
compiler other than C-Front. (In general, I find it hard to understand
why anyone would inherit other than virtually.)
|> The feature would allow such interfaces and mixins to exist - I'm
|> not sure, but I think one can build good mixins combining this
|> feature with Coplien's curiously recurring pattern.The language
|> rules as they are now basically don't allow reasonably good mixins.
--
James Kanze mailto:kanze@gabi-soft.de
Conseils en informatique orientie objet/
Beratung in Objekt orientierter Datenverarbeitung
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
---
[ 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: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/02/08 Raw View
<kanze@gabi-soft.de> wrote in message news:86r9eopvns.fsf@gabi-soft.de...
> Most of the bad record concerns space, not time, and is due to an error
> in C-Front. I've worked on a lot of applications where virtual
> inheritance was the rule, and it has never caused problems with any
> compiler other than C-Front. (In general, I find it hard to understand
> why anyone would inherit other than virtually.)
In general, a fair point, but it is only by inheriting non-virtually
that we are able to persuade the compiler to generate v-tables
with a layout suitable for Microsoft's COM.
Incidentally, what was the error in C-Front?
---
[ 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: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/02/08 Raw View
"Andrei Alexandrescu" <andrewalex@hotmail.com> wrote in message
news:s9q1ooms98e28@news.supernews.com...
> The proposal is the language to allow disambiguated diamond-MI from
classes
> as long as they don't have data members. This is easy to implement and
> doesn't break existing programs.
So if my compiler implemented the proposal, and thereby failed to
flag the "ambiguity", it would still be compliant.
Actually, I'm not sure. Some hardened template hacker (mentioning
no names Andrei) might have written a template that cunningly fails
to compile in the diamond-MI case.
That said, I like the proposal. Would it count as sufficiently minor to
adopt within the next five years?
---
[ 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: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/02/09 Raw View
"Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
>I have a proposal that I think it's quite sensible (duh!)
>
>Multiple inheritance from the same class is crippled by the problems that
>led to virtual inheritance.
>
>The problems with nonvirtual multiple inheritance stem from the existence of
>two base subobjects in the end object. Because of this, every access to a
>member of the superclass to which the two subobjects belong is ambiguous.
>
>If the base class is empty (does not have any member variables), however,
>the ambiguity problems dissapear as the two subobjects don't have
>distinguishable data.
>
>The proposal is the language to allow disambiguated diamond-MI from classes
>as long as they don't have data members. This is easy to implement and
>doesn't break existing programs.
In general the two sub-objects may remain distinguishable by their
different addresses. So some ambiguity problems remain.
For example, consider the following inheritance hierarchy,
where Base has no data members, but Left and Right
do have data members:
Base
/ \
Left Right
\ /
Derived
i.e.
struct Base { void foo(); }; // only function members
struct Left : Base { int x; };
struct Right : Base { int y; };
struct Derived : Left, Right {};
Now suppose Base::foo() examines the value of the `this'
pointer:
#include <iostream>
using std;
void Base::foo() {
cout << (void*) this;
}
int main() {
Derived d;
Left &l = d;
Right &r = d;
l.foo();
r.foo();
d.foo();
}
Here l.foo() and r.foo() must report different values
for the `this' pointer; To require them to report the
same values for the `this' pointer would impose the same
efficiency costs as you get with virtual inheritance.
So which value should d.foo() report: should it report
the value returned by l.foo(), or should it report
the value returned by r.foo()?
It's ambiguous. Leaving it unspecified is undesirable, since
that could lead to programs behaviour different on different
implementations, but specifying that these kind of ambiguous
conversions from Derived& to Base& always go via e.g. the left-most
path would be rather arbitrary.
You may also run into problems because (Base *)(Left *)&d
is not the same as (Base *)(Right *)&d. In particular,
if you're registering objects for callbacks, then you
may find the same object gets registered twice because
it has more than `Base *' address. So the behaviour
would not be the same as with virtual inheritance.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/02/09 Raw View
kanze@gabi-soft.de writes:
>"Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
>
>|> [...] nobody wants to inherit virtually unless they
>|> really need to. This has to do with the bad efficiency record that
>|> virtual inheritance has.
>
>Most of the bad record concerns space, not time, and is due to an error
>in C-Front. I've worked on a lot of applications where virtual
>inheritance was the rule, and it has never caused problems with any
>compiler other than C-Front. (In general, I find it hard to understand
>why anyone would inherit other than virtually.)
That may well be a reasonable position.
However, arguments like this were not sufficient to convince
the C++ committee to use virtual inheritance for the standard
exceptions hierarchy.
You can argue that the cost is small, but the fact that there
is a cost is unarguable, and as long as there is any cost, it
is likely that there will be at least some people who don't
want to pay that cost.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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: Ted Neward <tneward@edfund.org>
Date: 2000/02/09 Raw View
> |> This is how Java interfaces are implemented, I think. I guess this
> |> proposal has been discussed, right?
>
> I'm not sure how Java interfaces are implemented in detail, but the
> problem is different in Java; because *only* interfaces may be
> inherited, you have a priviledged branch. When comparing pointers, I
> suspect that the pointer values are always cast to Object first, and
> because Object is a class and not an interface, it can occur only once
> in the inheritance lattice.
>
I've not done C++ for a while (about 18 months or so)*, but I'm
neck-deep
in Java, so hopefully I can contribute the "Java angle" to the
discussion.
The Java compiler handles most of the interface magic, and is almost
exactly similar to the following:
public interface Interface
{
public void foo();
}
public class Class
implements Interface
{
public void foo() { ... } // Java compilation rules force
// this to be here--otherwise,
// Class is marked "abstract"
}
=====> The same as
class Interface
{
public:
virtual void foo();
};
class Class : public Interface
{
public:
virtual void foo()
{ ... }
};
This way, when the JVM begins execution, it can do a standard
"invokevirtual" opcode call on the Class object, and it never even
knows the method was specified by an interface. There really is no
runtime magic involved, so far as I can tell.
The key is that Java really doesn't have pointers, as we think of
pointers, anyway--they're opaque "pointers" to an object, granted,
and you can cast them like pointers, and so forth, but because the JVM
is free to implement its internal representation of an object however
it wishes, the "class representation" details we go over so
painstakingly
in C++ become almost completely irrelevant in Java. "Casting" is done
at the JVM level, and is entirely up to the JVM to decide how to
support.
For details on the Java Virtual Machine, see
http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html
(And please, I'm not trying to espouse Java "over" C++, so no "Java vs
C++" discussions welcome.....)
Ted Neward
Java Instructor, DevelopMentor
http://www.javageeks.com/~tneward
(*) -- I still like to follow my first language, though. :)
======================================= MODERATOR'S COMMENT:
Any followups which aren't related to the C++ Standard should be taken
to one of the comp.lang.java groups.
---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 2000/02/09 Raw View
Fergus Henderson <fjh@cs.mu.OZ.AU> wrote in message
news:87o3qc$7lt$1@mulga.cs.mu.OZ.AU...
> "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
> In general the two sub-objects may remain distinguishable by their
> different addresses. So some ambiguity problems remain.
This is correct. The proposal that I made can possibly break existing code -
at Base level, there's no more object identity - with current rules, the
pointers are different, with my rules, they are the same.
At least in theory, this could break some programs.
I would be glad to hear from actual compiler implementers how their object
model for virtual inheritance from empty base classes (virtuals only) look
like.
What I don't like about virtual inheritance, aside from efficiency issues,
is that you must decide early for something that usually happens late.
Andrei
---
[ 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: "Richard Parkin" <rparkin@msi-eu.com>
Date: 2000/02/10 Raw View
Ted Neward <tneward@edfund.org> wrote in message
news:38A06A86.C6290328@edfund.org...
> The Java compiler handles most of the interface magic, and is almost
> exactly similar to the following:
>
> public interface Interface
> {
> public void foo();
> }
> public class Class
> implements Interface
> {
> public void foo() { ... } // Java compilation rules force
> // this to be here--otherwise,
> // Class is marked "abstract"
> }
> =====> The same as
Close, but not quite - see corrections:
>
> class Interface
> {
> public:
> virtual void foo();
virtual void foo() = 0;
> };
> class Class : public Interface
class Class : public virtual Interface
> {
> public:
> virtual void foo()
> { ... }
> };
It's having to include the virtual keyword when deriving from a completely
abstract class that Andrei is proposing to drop.
As for his suggestion, I've thought about it before after realising the
neccessity of that pesky virtual, and think it has some merit. However, I
don't think it will be accepted because:
1) The object identity problem could break code
2) The problem can be avoided with the current language if everyone just
remembers to put in virtual.
I suppose we could all start using
#define implements public virtual
Ric
---
[ 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: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/02/10 Raw View
"Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
>Fergus Henderson <fjh@cs.mu.OZ.AU> wrote in message
>news:87o3qc$7lt$1@mulga.cs.mu.OZ.AU...
>> "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
>> In general the two sub-objects may remain distinguishable by their
>> different addresses. So some ambiguity problems remain.
>
>This is correct. The proposal that I made can possibly break existing code -
>at Base level, there's no more object identity - with current rules, the
>pointers are different, with my rules, they are the same.
If your rules require the pointers to be the same,
then don't you have to pay the same efficiency costs
as would be required for virtual inheritence?
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 2000/02/11 Raw View
Fergus Henderson <fjh@cs.mu.OZ.AU> wrote in message
news:87qjr0$bgq$1@mulga.cs.mu.OZ.AU...
> "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
>
> >Fergus Henderson <fjh@cs.mu.OZ.AU> wrote in message
> >news:87o3qc$7lt$1@mulga.cs.mu.OZ.AU...
> >> "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
> >> In general the two sub-objects may remain distinguishable by their
> >> different addresses. So some ambiguity problems remain.
> >
> >This is correct. The proposal that I made can possibly break existing
code -
> >at Base level, there's no more object identity - with current rules, the
> >pointers are different, with my rules, they are the same.
>
> If your rules require the pointers to be the same,
> then don't you have to pay the same efficiency costs
> as would be required for virtual inheritence?
To tell you the truth, I'm confused :o).
The more I think of it, the more I realize what I actually want.
Once you use multiple nonvirtual inheritance, you are lost in a sea of
ambiguities. I think the rules are too harsh. If the base of the diamond
does not have data members, function calls can be disambiguated to call
into, say, the first base in the lattice.
But now I realize that anyway my proposal can break existing code. I'm
curious to find information in depth about the Java object model. There,
interfaces are prohibited from holding data members and I feel the absence
of data members makes for an important difference. This difference could be
exploited automatically by a C++ compiler.
Andrei
---
[ 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: Darin Adler <darin@bentspoon.com>
Date: 2000/02/11 Raw View
In article <sa4i3fch53n97@news.supernews.com>, "Andrei Alexandrescu"
<andrewalex@hotmail.com> wrote:
> I'm curious to find information in depth about the Java object model.
> There, interfaces are prohibited from holding data members and I feel
> the absence of data members makes for an important difference. This
> difference could be exploited automatically by a C++ compiler.
Java interfaces are even simpler. The interfaces have no data members as
you say, but they also have no function members in an important sense!
The only have what we call pure virtual function members in C++, with no
implementation. They simply define the names and parameters of functions.
-- Darin
---
[ 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: Hyman Rosen <hymie@prolifics.com>
Date: 2000/02/11 Raw View
"Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
> But now I realize that anyway my proposal can break existing code. I'm
> curious to find information in depth about the Java object model. There,
> interfaces are prohibited from holding data members and I feel the absence
> of data members makes for an important difference. This difference could be
> exploited automatically by a C++ compiler.
The Java interface model is (almost) entirely equivalent to C++
virtual abstract base classes without data members. That is, if
in Java you write 'class C implements I', in C++ you would write
'class C : public virtual I'.
The almost is because Java lets you inherit interface implementations
from base classes, and C++ does not. That is, in Java you can write -
class M { public void f() { } }
interface I { void f(); }
class F extends M implements I { } // F.M.f() satisfies F.I.f()
whereas in C++ you must forward -
struct M { void f() { } };
struct I { virtual void f() = 0; }
struct F : M, virtual I { void f() { M::f(); } };
Remember that Java has cross-casting just like C++ does, so a
certain amount of complexity must be present -
interface I { void f(); }
interface J { void g(); }
class C implements I, J
{
public void f() { }
public void g() { }
}
class D
{
void f(I i) { }
void g(J j) { f((I)j); }
public static void main(String[] v) { g(new 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://reality.sgi.com/austern_mti/std-c++/faq.html ]