Topic: multiple inheritance question
Author: dyang@rapnet.sanders.lockheed.com (David Yang)
Date: 20 Jun 1994 15:53:14 GMT Raw View
Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
: No, that's not correct. See ARM 10, page 196:
:
: "Unless redefined in the derived class, members of a base class
: can be referred to as if they were members of the derived
: class. The base class members are said to be _inherited_ by
: the derived class." [Their italics.]
:
: There is no copying involved.
:
No, not at all. I didn't mean "getting a copy" in a literal sense. What
I meant was that if you take DCLASS by itself, and list all its members
regardless of the scope in which they are declared, A::f() and B::f()
would be included. Maybe a bad choice of words...
I notice that the passage you quoted doesn't seem to consider inherited
members to be actual members of a derived class, though they can be "referred
to as if they were". I didn't get a clear picture from Stroustrup, but in
Weiskamp & Flamig:
A derived class has all the members of the base class, plus addi-
tional ones. Even if you override a base class function with a
derived class version, the base class function is still there. [p328]
Elsewhere there's a diagram of of a derived class which include all the
inherited funcs as members. It went on to talk about how the class
"has" 2 sets of functions with identical names etc.
: This raises the question of what the ARM means when it says
: [ARM 10.3, page 214]:
:
: "A class is abstract if it has at least one pure virtual function."
:
: What does "has" mean here? This is one of the areas where the ARM and
: the working paper are ambiguous and incomplete. The examples seem to
: suggest that a class `C' "has" a pure virtual function `f' iff `C::f'
: is pure, where `C::f' can of course refer to an inherited function
: which is not a member of C.
Yeah, "has" is not a clear concept. Weiskamp & Flamig seem to say that
an inherited member is still a member.
: Since there is no function `f' for which
: `DCLASS::f' is pure virtual, I would say that DCLASS is not abstract.
: And from a a common-sense point of view, since there is no way to call
: a pure virtual function on an object of class DCLASS without an
: explicit scope qualifier, there is no reason to disallow creation of
: objects of DCLASS.
Again, W&F seem to make sense here: If C::f() is considered a member of
DCLASS that explains why it is abstract. The scope qualifier only specifies
the scope where name look-up is to begin and is not necessarily related to
class membership. Scoping can hide a class member but can't make it go away.
I would guess that the compiler can figure out pure virtual A::f() has
been defined in B during the check for ambiguity. But it seems that the
check for abstract instantiation comes before that.
Dave
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 21 Jun 1994 16:12:51 GMT Raw View
dyang@rapnet.sanders.lockheed.com (David Yang) writes:
>Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
>: No, that's not correct. See ARM 10, page 196:
[...]
>: There is no copying involved.
>
>No, not at all. I didn't mean "getting a copy" in a literal sense. What
>I meant was that if you take DCLASS by itself, and list all its members
>regardless of the scope in which they are declared, A::f() and B::f()
>would be included.
Well, according to the ARM and the ANSI/ISO working paper,
A::f() and B::f() would not be included.
>I notice that the passage you quoted doesn't seem to consider inherited
>members to be actual members of a derived class, though they can be "referred
>to as if they were".
Yes, exactly.
>I didn't get a clear picture from Stroustrup, but in
>Weiskamp & Flamig:
>
> A derived class has all the members of the base class, plus addi-
> tional ones. Even if you override a base class function with a
> derived class version, the base class function is still there. [p328]
Yeah, well I guess that just means that Wieskamp & Flamig are wrong -
or to be fair, slightly misleading.
>Yeah, "has" is not a clear concept. Weiskamp & Flamig seem to say that
>an inherited member is still a member.
Well, that's fine, but the problem is that it doesn't really matter
what Weiskamp and Flamig think, unless the ANSI/ISO committee agree with them.
The only really authoratitive references are the ANSI/ISO C++ committee's
working paper, the ARM, Stroustrup, and the ANSI/ISO C standard.
>Again, W&F seem to make sense here: If C::f() is considered a member of
>DCLASS that explains why it is abstract.
But according to their words
> Even if you override a base class function with a
> derived class version, the base class function is still there. [p328]
so that would mean that for *any* class `Derived' that inherited from a class
`Base' containing a pure virtual function `f', `Derived' would contain
`Base::f()' which would be pure, and hence `Derived' would be abstract.
In other words, there would be no way to make a concrete class derived
from an abstract one!
There are two questions involved here. Number one is whether the code
*is* legal, according to the current C++ defacto standard based on the
ANSI/ISO committee's working paper and the ARM. My interpretation of
these documents is that they support the position that the code is legal,
although they are certainly not very clear on the issue.
The second question is whether it *should* be legal. My opinion is
that is should indeed be legal, since allowing it is not dangerous (it
does not make it possible to call a pure virtual without using a scope
qualifier), is not difficult to implement, and would support a useful
style of programming.
--
Fergus Henderson - fjh@munta.cs.mu.oz.au
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Wed, 22 Jun 1994 22:16:04 GMT Raw View
In article <2u4e1a$gqs@rapnet.sanders.lockheed.com> dyang@rapnet.sanders.lockheed.com (David Yang) writes:
>Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
>: No, that's not correct. See ARM 10, page 196:
>:
>: "Unless redefined in the derived class, members of a base class
>: can be referred to as if they were members of the derived
>: class. The base class members are said to be _inherited_ by
>: the derived class." [Their italics.]
note it says "as if".
>:
>No, not at all. I didn't mean "getting a copy" in a literal sense. What
>I meant was that if you take DCLASS by itself, and list all its members
>regardless of the scope in which they are declared, A::f() and B::f()
>would be included. Maybe a bad choice of words...
And its a bad description. It leads to the mistake
(and its clearly and unequivocably an invalid interpretation)
in thinking that:
class A { virtual f()=0; };
class B : A { f(); };
class C : A, B {};
class C is abstract because it 'has' the member A::f().
It does NOT have such a member.
>
>I notice that the passage you quoted doesn't seem to consider inherited
>members to be actual members of a derived class, though they can be "referred
>to as if they were". I didn't get a clear picture from Stroustrup, but in
>Weiskamp & Flamig:
>
> A derived class has all the members of the base class, plus addi-
> tional ones. Even if you override a base class function with a
> derived class version, the base class function is still there. [p328]
Obviously wrong or quoted out of context.
"the" base class ignores multiple inheritance.
>
>Yeah, "has" is not a clear concept. Weiskamp & Flamig seem to say that
>an inherited member is still a member.
The meaning of "has" is literal but the correct wording
should read
"for each member of a base class there exists a corresponding
member of the derived class: such a member will be generated
by the compiler"
That is, given:
class A { void f(); };
class B : A {};
B does NOT contain the function A::f(). It cant. Not possible.
Out of the question. A::f() could not possibly be called,
the type of the 'this' pointer is wrong.
Instead an "inherited" member of B is generated by the compiler
which takes a this pointer of type B* and converts it
to an A* and THEN calls A::f(): writing the 'this' pointer
parameter out explicitly:
class B : A {
inherited_A_f(B* this)
{
A* Athis = this;
A::f(Athis);
}
};
Real compilers DO use this function. Of course its
usually inlined, and the conversion of the this pointer
can be optimised away sometimes (always with single inheritance).
This model of inhertance can be extended to cope with virtual
functions.
It also explains pointers to member functions.
That is, a pointer to member:
void A::(*pf)()
really does have to be converted to a different pointer
void B::(*pf)()
because BOTH functions then really exist and have quite
different addresses. With this model, a pointer to
member function is exactly a single machine address of a function.
The reverse conversion should be banned because its absurd:
no such base function need exist. If it did, you'd have the
choice of changing the address or not: the first case
allows the base function to be called and allows conversion
back by the normal (safe) conversion process, the second case
allows conversion in one direction and then breaks.
This can be "fixed" by only doing the conversion if its possible,
otherwise just copying the address. But I think thats stinks:
the same conversion would either be a genuine value conversion
or a reinterpret cast - depending.
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd, CSERVE:10236.1703
6 MacKay St ASHFIELD, Mem: SA IT/9/22,SC22/WG21
NSW 2131, AUSTRALIA
Author: jason@cygnus.com (Jason Merrill)
Date: Sat, 18 Jun 1994 01:40:29 GMT Raw View
>>>>> David Yang <dyang@rapnet.sanders.lockheed.com> writes:
> Not quite. In either case DCLASS gets a copy of both BCLASS::f() and
> ACLASS::f() (from CCLASS). If ACLASS::f() is defined then ambiguity
> resolution kicks in. If ACLASS::f() is pure virtual DCLASS would wind up
> with a function with no body, and is by definition abstract.
ACLASS::f() is hidden by BCLASS::f(), even though it can be reached by
through CCLASS. It seems very non-orthogonal for this behavior to change
depending on whether or not ACLASS::f() is pure virtual, and I don't see
anything in the WP to support that interpretation.
Jason
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sun, 19 Jun 1994 07:50:32 GMT Raw View
dyang@rapnet.sanders.lockheed.com (David Yang) writes:
>Jason Merrill (jason@cygnus.com) wrote:
>: >>>>> li-ming ren <ren@cis.ohio-state.edu> writes:
>:
>: > Shouldn't the same thing happen when f() is left undefined (pure) in
>: > ACLASS?
>:
>: I believe so, yes.
>
>Not quite. In either case DCLASS gets a copy of both BCLASS::f() and
>ACLASS::f() (from CCLASS).
No, that's not correct. See ARM 10, page 196:
"Unless redefined in the derived class, members of a base class
can be referred to as if they were members of the derived
class. The base class members are said to be _inherited_ by
the derived class." [Their italics.]
There is no copying involved.
This raises the question of what the ARM means when it says
[ARM 10.3, page 214]:
"A class is abstract if it has at least one pure virtual function."
What does "has" mean here? This is one of the areas where the ARM and
the working paper are ambiguous and incomplete. The examples seem to
suggest that a class `C' "has" a pure virtual function `f' iff `C::f'
is pure, where `C::f' can of course refer to an inherited function
which is not a member of C. Since there is no function `f' for which
`DCLASS::f' is pure virtual, I would say that DCLASS is not abstract.
And from a a common-sense point of view, since there is no way to call
a pure virtual function on an object of class DCLASS without an
explicit scope qualifier, there is no reason to disallow creation of
objects of DCLASS.
>If ACLASS::f() is defined then ambiguity
>resolution kicks in. If ACLASS::f() is pure virtual DCLASS would wind up
>with a function with no body, and is by definition abstract.
Whether or not a function is pure virtual and whether or not it is
defined are orthogonal issues - it is quite possible to give a definition
of a pure virtual.
--
Fergus Henderson - fjh@munta.cs.mu.oz.au
Author: ren@cis.ohio-state.edu (li-ming ren)
Date: 16 Jun 1994 11:05:42 -0400 Raw View
Saw the following question in a local newsgroup. I am wondering what the
standard says about this. I tried use g++ and it worked.
--------
Consider the following program where ACLASS contains a pure virtual
function f(), BCLASS and CCLASS inherit from ACLASS, and DCLASS inherits
BCLASS and CCLASS. BCLASS defines function f(), so I expect DCLASS to use
the function f() from BCLASS. However, when I compile the following
code on the ATT C++ compiler, I receive the message that DCLASS is
an abstract base class. If I define f() in ACLASS, then the whole
thing compiles properly and DCLASS uses the definition of f() from
BCLASS as expected. Shouldn't the same thing happen when f() is
left undefined (pure) in ACLASS?
#include <iostream.h>
class ACLASS {
public:
int x;
virtual void f() = 0;
};
class BCLASS : virtual public ACLASS {
public:
void f(){cout << "B" << endl;};
};
class CCLASS : virtual public ACLASS {
public:
int y;
};
class DCLASS : virtual public BCLASS, virtual public CCLASS{
public:
int z;
};
main()
{
DCLASS d;
d.f();
};
---------------
--
Liming Ren | Dept.of Computer and Information Science
Office BO247, 2-4029 | The Ohio State University
ren@cis.ohio-state.edu | Columbus, OHIO43210
Author: jason@cygnus.com (Jason Merrill)
Date: Thu, 16 Jun 1994 22:16:32 GMT Raw View
>>>>> li-ming ren <ren@cis.ohio-state.edu> writes:
> Shouldn't the same thing happen when f() is left undefined (pure) in
> ACLASS?
I believe so, yes.
Jason
Author: dyang@rapnet.sanders.lockheed.com (David Yang)
Date: 17 Jun 1994 17:09:21 GMT Raw View
Jason Merrill (jason@cygnus.com) wrote:
: >>>>> li-ming ren <ren@cis.ohio-state.edu> writes:
:
: > Shouldn't the same thing happen when f() is left undefined (pure) in
: > ACLASS?
:
: I believe so, yes.
:
: Jason
Not quite. In either case DCLASS gets a copy of both BCLASS::f() and
ACLASS::f() (from CCLASS). If ACLASS::f() is defined then ambiguity
resolution kicks in. If ACLASS::f() is pure virtual DCLASS would wind up
with a function with no body, and is by definition abstract.
Dave