Topic: rationale for hiding virtual fns
Author: rjl@f111.iassf.easams.com.au (Rohan LENARD)
Date: 5 Mar 1995 07:12:41 +1000 Raw View
Hi there,
In article <3j6pme$t0f@etca.etca.fr>,
Christian Millour <chris@alofi.etca.fr> wrote:
>hello world.
>
>given
> class A {public: virtual void f(A*);}
> class B {public: virtual void f(B*);}
> class C: public A, public B {public: virtual void f(B*);}
>the following line
> aCptr->f(anAptr);
>will not compile owing to the fact that A::f(A*) is hidden
>by the definition of C::f(B*), as the compiler warns about.
>I can live with it but am curious about the rationale for
>this hiding, as the call looks totally unambiguous. From
>C++PL2nd and D&EofC++ there is a dominance rule involved that
>operates on function names rather than full signatures. Why
>is it so ?
I quote from the ARM (13.1 Declaration Matching - pg 311) which
describes the basic philosophy -
"One might consider ignoring scope issues when resolving overloaded
function; that is, consider every function that would be in scope
had it not been hidden by a name in an enclosed scope. This, however
would lead to surprises when an unsuspected function was invoked by
a call. For example,
class X1 {
public:
void f(int);
};
// chain of derivations X(n) : X(n-1)
class X9 : public X8 {
public:
void f(double);
};
void g(X9* p)
{
p->f(2); // X9::f() or X1::f()
}
Unless the programmer has an unusually deep understanding of the
program, the assumption will be that p->f(2) calls X9::f() - and not
X1::f() declared deep in the base class. Under the C++ rules, this
is indeed the case.
Had the rules allowed X1::f(int) to be chosen as a better match,
unintentional overloading of unrelated functions would be a distinct
possibility. In general, protection against accidental overloading is
not easy for a compiler to provide, but see %10.2 for a discussion of
how it might be handled for virtual functions. Virtual functions -
which are by definition meant to be defined, overridden, calles at
different levels of a clas lattice, and so on - are the ones for which
these problems most naturally occur. If the intent really were to call
X1::f(), the declaration of X9 can be modified to ensure that.
"
Regards,
Rohan
--
----------------------------------------------------------------------------
rjl@iassf.easams.com.au | All quotes can be attributed to my automated quote
Rohan Lenard | writing tool. Yours for just $19.95; and if you
+61-2-367-4555 | call now you'll get a free set of steak knives ...
Author: chris@alofi.etca.fr (Christian Millour)
Date: 3 Mar 1995 10:06:06 GMT Raw View
hello world.
given
class A {public: virtual void f(A*);}
class B {public: virtual void f(B*);}
class C: public A, public B {public: virtual void f(B*);}
the following line
aCptr->f(anAptr);
will not compile owing to the fact that A::f(A*) is hidden
by the definition of C::f(B*), as the compiler warns about.
I can live with it but am curious about the rationale for
this hiding, as the call looks totally unambiguous. From
C++PL2nd and D&EofC++ there is a dominance rule involved that
operates on function names rather than full signatures. Why
is it so ?
TIA for any explanation or pointers,
--chris@etca.fr
Le monde entier est un cactus, il est impossible de s'asseoir (J. Dutronc)
Author: Ian T Zimmerman <itz@rahul.net>
Date: 3 Mar 1995 15:18:39 GMT Raw View
In article <3j6pme$t0f@etca.etca.fr>,
Christian Millour <chris@alofi.etca.fr> wrote:
>hello world.
>
>given
> class A {public: virtual void f(A*);}
> class B {public: virtual void f(B*);}
> class C: public A, public B {public: virtual void f(B*);}
>the following line
> aCptr->f(anAptr);
>will not compile owing to the fact that A::f(A*) is hidden
>by the definition of C::f(B*), as the compiler warns about.
>I can live with it but am curious about the rationale for
>this hiding, as the call looks totally unambiguous. From
>C++PL2nd and D&EofC++ there is a dominance rule involved that
>operates on function names rather than full signatures. Why
>is it so ?
>
This code defines _two unrelated_ functions. B::f() _hides_ but
doesn't _override_ A::f(). So the dominance rule which handles
overriding doesn't apply in this case, and the call is considered
suspect by the compiler for the same reason as if you have written
class A {public: virtual void f(int);}
class B {public: f(double);}
...
int i;
aBptr->f(i);
See ARM section 10.2, D&E section 13.7.
cheers, itz.
--
Ian T Zimmerman +-------------------------------------------+
P.O. Box 13445 I With so many executioners available, I
Berkeley, California 94712 I suicide is a really foolish thing to do. I
USA <itz@rahul.net> +-------------------------------------------+