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>       +-------------------------------------------+