Topic: virtual functions in derived classes


Author: media@netcom.com (Max Headroom)
Date: Tue, 26 Jul 1994 22:16:51 GMT
Raw View
In article <3064vo$g35@hpsystem1.informatik.tu-muenchen.de>, schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
>
> In article <3049dp$5kc@crl2.crl.com>, danap@crl.com (Dana P'Simer) writes:
> |> ...
> |> The virtual key word is not neccessary in definitions of overrided virtual
> |> functions in derived class definitions.  The virtual property of the member
> |> is retained through any number of derivations wheather the virtual keyword
> |> is used or not.
>
> In all projects if've been/am working, I use "virtual" also in any redefinition
> of a virtual method. This ensures that I do not forget that I am overwriting
> a virtual method. And this ensures that no-one looking at my headers oversees
> that this is a virtual method (this means it depends on the dynamic type of the
> object and not 'just' on it's static type).



Author: doug@monet.ads.com (Doug Morgan)
Date: 18 Jul 94 16:02:07
Raw View
In article <1994Jul16.002755.19031@midway.uchicago.edu> iroberts@ellis.uchicago.edu (Ian B. Robertson) writes:
>...
>Is there any way to achieve different behavior than this?  I would
>like to be able to define an abstract class, Ring, with pure virtual
>functions for multiplication, addition, and so forth.  Derived classes
>could included Integer, Rational, Z_Mod_P, and so forth.  In some
>cases, I might want to be able to pass an arbitrary ring to a
>function expecting an object of class Ring, and in this case I would
>need these functions to be virtual.  However, if I'm writing code
>especially for the Z_Mod_P class, for example, then I would like to
>avoid pointer lookups for every call.  It seems like there ought to be
>a way to achieve this mixture of abstraction and efficiency (perhaps
>through some means other than virtual functions).  Any ideas?
>- Ian Robertson
>i-robertson@uchicago.edu


Define the function for Ring to be an inline call to a virtual
function that actually does the work.  Redefine the virtual function
as necessary for Ring subclasses.  For Z_Mod_P, redefine the original
inline function to just do the work directly.  You then get precisely
the behavior you want.  Be careful to not derive from Z_Mod_P in a way
that contradicts the now hardwired meaning of the non-virtual
function.

Doug
--------------------------------------------------------------------
Doug Morgan, doug@ads.com, (415) 960-7444
Advanced Decision Systems (a division of Booz-Allen & Hamilton Inc.)
1500 Plymouth St., Mountain View, CA 94043-1230
--------------------------------------------------------------------




Author: olaf@cwi.nl (Olaf Weber)
Date: Tue, 19 Jul 1994 09:41:52 GMT
Raw View
In article <LDH.94Jul18124431@tahiti.cs.brown.edu>, ldh@cs.brown.edu (Laurent Hasson) writes:

> Imagine you have the following configuration:

[Example rewritten]

class A {
public:
    virtual void a();
};

class B : public A {
private:
    void a();
};

class C : public B {  // I assumed C was to be derived from B, not A
public:
    void a();
};

Cases like this one are dealt with in section 11.6 of the ARM: "Access
to Virtual Functions".

> Now, If i have an object of type B, cast into A*.... i call A->a(),
> this should not work since B::a is private. I think. But i am not sure
> that's the way it works. Is that right?

The call would be legal.  After all, it would be odd if a public
member of A cannot be called through a pointer to an A for some A's,
but not others.  It would produce troublesome runtime bugs.

> But after B, is "a" still virtual ?

Yes.

> Technically, the scope of C does not have access to B::a(), and
> therefore, C::a() should be a different function, with no
> "relationship" with the previously overloaded virtual a?

No.  The virtual mechanism and access control are orthogonal.  While
you cannot access B::a() from members of C, you can override it.  For
example:

void f()
{
 C c;           B b;           A a;
 A * pca = &c;  A * pba = &b;  A * paa = &a;
 B * pcb = &c;  B * pbb = &b;
 C * pcc = &c;

 // Legal, call C::a(), B::a() and A::a() respectively.
 pca->a();      pba->a();      paa->a();

 // Illegal, B::a() is inaccessible in f().
 pcb->a();      pbb->a();

 // Legal, calls C::a().
 pcc->a();
}

-- Olaf Weber




Author: johnl@krell.gte.com (John X. Laporta)
Date: 19 Jul 1994 18:35:27 GMT
Raw View
In article <DOUG.94Jul18160207@monet.ads.com> doug@monet.ads.com (Doug Morgan) writes:

   Define the function for Ring to be an inline call to a virtual
   function that actually does the work.

   Doug
   --------------------------------------------------------------------
   Doug Morgan, doug@ads.com, (415) 960-7444
   Advanced Decision Systems (a division of Booz-Allen & Hamilton Inc.)
   1500 Plymouth St., Mountain View, CA 94043-1230
   --------------------------------------------------------------------

Danger! Several compilers I have used exhibit an intermittent bug
when virtual functions are implicitly or explicitly declared inline.
This has happened to me in five different programming contexts on
three different compilers. Sometimes there is no problem. Add some
code, however, and you can be in a function where all the data is
correct, then you leave that function, and all data in the program
is corrupt. Add some more code and the problem may go away. This
bug is extremely hard to detect unless you know that the use of
virtual inlines is dangerous. Also, the concept of a virtual inline
doesn't make sense anyway.

--
John X. Laporta
Senior Member of Technical Staff
GTE Laboratories Incorporated
40 Sylvan Road
Waltham MA 02254 USA
(617) 466-2095
jxl0@gte.com




Author: doug@monet.ads.com (Doug Morgan)
Date: 22 Jul 94 08:37:32
Raw View
In article <JOHNL.94Jul19143527@krell.gte.com> johnl@krell.gte.com (John X. Laporta) writes:
:In article <DOUG.94Jul18160207@monet.ads.com> doug@monet.ads.com (Doug Morgan) writes:
::Define the function for Ring to be an inline call to a virtual
::function that actually does the work.
::
::Doug
:
:Danger! Several compilers I have used exhibit an intermittent bug
:when virtual functions are implicitly or explicitly declared inline.
:This has happened to me in five different programming contexts on
:three different compilers. Sometimes there is no problem. Add some
:code, however, and you can be in a function where all the data is
:correct, then you leave that function, and all data in the program
:is corrupt. Add some more code and the problem may go away. This
:bug is extremely hard to detect unless you know that the use of
:virtual inlines is dangerous. Also, the concept of a virtual inline
:doesn't make sense anyway.
:
:--
:John X. Laporta

Although I have never noticed bugs like you mention, I also didn't say
anything about virtual inline (which, by the way, does make sense when
the compiler can "see" the definition of the relevant object in the
call of the virtual).  I said use an inline function that calls a
virtual.  E.g.:

class Ring {
  int virtual a_virtual_function();
public:
  // This is what I said (note, no virtual):
  int the_exported_function() {return a_virtual_function();}
};

// This completes the example:
class Z_Mod_P : public Ring {
  // OK, so I can use a virtual inline here (for simplicity)
  int virtual a_virtual_function() {return the_exported_function();}
public:
  int the_exported_function() {/* Hardwired implementation */}
};

Doug
--------------------------------------------------------------------
Doug Morgan, doug@ads.com, (415) 960-7444
Advanced Decision Systems (a division of Booz-Allen & Hamilton Inc.)
1500 Plymouth St., Mountain View, CA 94043-1230
--------------------------------------------------------------------




Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 22 Jul 1994 18:18:00 GMT
Raw View
In article <308ec1$bee@search01.news.aol.com>, objfactory@aol.com (ObjFactory) writes:
|> In article <3064vo$g35@hpsystem1.informatik.tu-muenchen.de>,
|> schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
|>
|> >...
|> >In all projects if've been/am working, I use "virtual" also in any
|> redefinition
|> >of a virtual method. This ensures that I do not forget that I am
|> overwriting
|> >a virtual method. And this ensures that no-one looking at my headers
|> oversees
|> >that this is a virtual method...
|>
|> Yes, but it is still true that neither the compiler nor the human reader
|> can tell from such a declaration that you intend to override a base class
|> function vs. declare a new virtual function. Consequently, if you get the
|> parameter types of your "override" even slightly wrong, e.g., by leaving
|> out a "const", you will find yourself doing the the latter when you intend

You are right.
With a compilerswitch gcc issues a warning when you declare a method
and there is a inherited virtual method with the same name, that will not be
overridden but just overloaded by this declaration.
I can live with this.

|> the former. If C++ were more concerned with preventing common mistakes, it
|> would provide a way to specify that a given declaration is an override as
|> opposed to an overload. (But it ain't.)
|> Bob Foster
|> Object Factory
|> objfactory@aol.com


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sun, 24 Jul 1994 11:08:26 GMT
Raw View
johnl@krell.gte.com (John X. Laporta) writes:

>Danger! Several compilers I have used exhibit an intermittent bug
>when virtual functions are implicitly or explicitly declared inline.
[...]

Alert!  I detect some FUD at work here.
No offence intended to John X. Laporta, but I think a much more likely
explanation is that his program contained an intermittent bug, which he
is erroneously attributing to the use of inline virtual functions.
Unless he offers some concrete evidence of the alleged compiler bugs,
his comments are just FUD (Fear, Uncertainty, Doubt).

>Also, the concept of a virtual inline doesn't make sense anyway.

It makes perfect sense.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: hans@xelion.nl (Hans Bos)
Date: Thu, 14 Jul 1994 17:22:39 GMT
Raw View
Hello,

When I redefine a function in a subclass, that is defined virtual in the
superclass, is the function also treated as a virtual function in the
subclass when it is defined without the virtual keyword?

E.g.
class base {
    virtual void func();
    ...
};

class subclass: public base {
    void func();
    ...
};

Now if func() is called for an object of type subclass, is it treated as
a virtual function, that may be redefined in a hypothetical subsubclas,
or does it always call subclass::func.

Thanks,
Hans Bos.
--
----------------------------------------------------------------------
Hans Bos                         domain : hans@xelion.nl
Xelion BV                          uucp   : ...!uunet!sun4nl!xelion!hans
Postbus 88                         phone  : +31 15 622121




Author: danap@crl.com (Dana P'Simer)
Date: 14 Jul 1994 14:07:05 -0700
Raw View
In article <CsxxLs.6uH@xelion.nl>, Hans Bos <hans@xelion.nl> wrote:
>Hello,
>
>When I redefine a function in a subclass, that is defined virtual in the
>superclass, is the function also treated as a virtual function in the
>subclass when it is defined without the virtual keyword?
>
>E.g.
>class base {
>    virtual void func();
>    ...
>};
>
>class subclass: public base {
>    void func();
>    ...
>};
>
>Now if func() is called for an object of type subclass, is it treated as
>a virtual function, that may be redefined in a hypothetical subsubclas,
>or does it always call subclass::func.

The virtual key word is not neccessary in definitions of overrided virtual
functions in derived class definitions.  The virtual property of the member
is retained through any number of derivations wheather the virtual keyword
is used or not.


--
Dana P'Simer
danap@crl.com
Objective Technologies




Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 15 Jul 1994 14:03:36 GMT
Raw View
In article <3049dp$5kc@crl2.crl.com>, danap@crl.com (Dana P'Simer) writes:
|> ...
|> The virtual key word is not neccessary in definitions of overrided virtual
|> functions in derived class definitions.  The virtual property of the member
|> is retained through any number of derivations wheather the virtual keyword
|> is used or not.
|>
|>
|> --
|> Dana P'Simer
|> danap@crl.com
|> Objective Technologies

In all projects if've been/am working, I use "virtual" also in any redefinition
of a virtual method. This ensures that I do not forget that I am overwriting
a virtual method. And this ensures that no-one looking at my headers oversees
that this is a virtual method (this means it depends on the dynamic type of the
object and not 'just' on it's static type).

I see that it may be too hard to force everybody to write "virtual" for every
redefinition (by making it standard), but I would appreciate if I could use a
compileroption to enforce this 'style' (by generating warnings if there is no
keyword "virtual" in a redefinition of a virtual member).

Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Institut f   r Informatik, Technische Universit   t M   nchen.
email: schuenem@informatik.tu-muenchen.de




Author: jfv@tid.es (Juan Fernandez Vazquez)
Date: Fri, 15 Jul 1994 14:34:28 GMT
Raw View
hans@xelion.nl (Hans Bos) writes:
: Hello,
:
: When I redefine a function in a subclass, that is defined virtual in the
: superclass, is the function also treated as a virtual function in the
: subclass when it is defined without the virtual keyword?
:
Yes. A C++ book is not so expensive. Buy one. ;-)

Juan.




Author: iroberts@ellis.uchicago.edu (Ian B. Robertson)
Date: Sat, 16 Jul 1994 00:27:55 GMT
Raw View
In article <3049dp$5kc@crl2.crl.com> danap@crl.com (Dana P'Simer) writes:
>In article <CsxxLs.6uH@xelion.nl>, Hans Bos <hans@xelion.nl> wrote:
>>Hello,
>>
>>When I redefine a function in a subclass, that is defined virtual in the
>>superclass, is the function also treated as a virtual function in the
>>subclass when it is defined without the virtual keyword?
>>
>
>The virtual key word is not neccessary in definitions of overrided virtual
>functions in derived class definitions.  The virtual property of the member
>is retained through any number of derivations wheather the virtual keyword
>is used or not.
>
>

Is there any way to achieve different behavior than this?  I would
like to be able to define an abstract class, Ring, with pure virtual
functions for multiplication, addition, and so forth.  Derived classes
could included Integer, Rational, Z_Mod_P, and so forth.  In some
cases, I might want to be able to pass an arbitrary ring to a
function expecting an object of class Ring, and in this case I would
need these functions to be virtual.  However, if I'm writing code
especially for the Z_Mod_P class, for example, then I would like to
avoid pointer lookups for every call.  It seems like there ought to be
a way to achieve this mixture of abstraction and efficiency (perhaps
through some means other than virtual functions).  Any ideas?
 - Ian Robertson
   i-robertson@uchicago.edu






Author: objfactory@aol.com (ObjFactory)
Date: 16 Jul 1994 06:56:01 -0400
Raw View
In article <3064vo$g35@hpsystem1.informatik.tu-muenchen.de>,
schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:

>...
>In all projects if've been/am working, I use "virtual" also in any
redefinition
>of a virtual method. This ensures that I do not forget that I am
overwriting
>a virtual method. And this ensures that no-one looking at my headers
oversees
>that this is a virtual method...

Yes, but it is still true that neither the compiler nor the human reader
can tell from such a declaration that you intend to override a base class
function vs. declare a new virtual function. Consequently, if you get the
parameter types of your "override" even slightly wrong, e.g., by leaving
out a "const", you will find yourself doing the the latter when you intend
the former. If C++ were more concerned with preventing common mistakes, it
would provide a way to specify that a given declaration is an override as
opposed to an overload. (But it ain't.)

Bob Foster
Object Factory
objfactory@aol.com




Author: barmar@think.com (Barry Margolin)
Date: 17 Jul 1994 01:11:25 GMT
Raw View
In article <1994Jul16.002755.19031@midway.uchicago.edu> iroberts@midway.uchicago.edu writes:
>However, if I'm writing code
>especially for the Z_Mod_P class, for example, then I would like to
>avoid pointer lookups for every call.  It seems like there ought to be
>a way to achieve this mixture of abstraction and efficiency (perhaps
>through some means other than virtual functions).  Any ideas?

If you call a member function using the syntax value.function() rather
than pointer->function() then virtual function resolution isn't done.

However, consider whether you really want to do this.  What if someone
derives a class from Z_Mod_P (e.g. creating Z_Mod_2_to_N) and overrides
some of Z_Mod_P's virtual member functions (when P is a power of 2, many
optimizations are possible)?  The intent of this is that the derived
class's versions should be invoked by your function (to take advantage of
the optimizations).  This is the essence of OOP.

--
Barry Margolin
System Manager, Thinking Machines Corp.

barmar@think.com          {uunet,harvard}!think!barmar




Author: pkron@corona.com (Peter Kron)
Date: Sun, 17 Jul 1994 08:39:19 PDT
Raw View
From: barmar@think.com (Barry Margolin)
>  If you call a member function using the syntax
>  value.function() rather than pointer->function() then
>  virtual function resolution isn't done.

Not quite. Value must be a known instance, not a reference.

void
test( Base& reference)
 {
 Base instance;

 reference.method();  // will use virtual semantics
 instance.method();  // can optimize out virtual semantics
 }
---
NeXTMail:peter.kron@corona.com
Corona Design, Inc.
P.O. Box 51022
Seattle, WA 98115-1022




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Mon, 18 Jul 1994 01:17:42 GMT
Raw View
In article <1994Jul16.002755.19031@midway.uchicago.edu> iroberts@midway.uchicago.edu writes:
>In article <3049dp$5kc@crl2.crl.com> danap@crl.com (Dana P'Simer) writes:
>>In article <CsxxLs.6uH@xelion.nl>, Hans Bos <hans@xelion.nl> wrote:
>>>Hello,
>>>
>>>When I redefine a function in a subclass, that is defined virtual in the
>>>superclass, is the function also treated as a virtual function in the
>>>subclass when it is defined without the virtual keyword?
>>>
>>
>>The virtual key word is not neccessary in definitions of overrided virtual
>>functions in derived class definitions.  The virtual property of the member
>>is retained through any number of derivations wheather the virtual keyword
>>is used or not.
>>
>>
>
>Is there any way to achieve different behavior than this?  I would
>like to be able to define an abstract class, Ring, with pure virtual
>functions for multiplication, addition, and so forth.  Derived classes
>could included Integer, Rational, Z_Mod_P, and so forth.  In some
>cases, I might want to be able to pass an arbitrary ring to a
>function expecting an object of class Ring, and in this case I would
>need these functions to be virtual.  However, if I'm writing code
>especially for the Z_Mod_P class, for example, then I would like to
>avoid pointer lookups for every call.  It seems like there ought to be
>a way to achieve this mixture of abstraction and efficiency (perhaps
>through some means other than virtual functions).  Any ideas?

Sure.  Try ~virtual.

(Just kidding.  Old timers may remember the idea of ~const, which later
mutated into `mutable'.)

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: ldh@cs.brown.edu (Laurent Hasson)
Date: Mon, 18 Jul 1994 17:44:31 GMT
Raw View
Imagine you have the following configuration:

class A
 { public:
     virtual void a(void);
     ....
 };

class B : public A
 { private:
     void a(void);
     ....
 };

class C : public A
 { public:
     void a(void);
     ...
 };

Now, If i have an object of type B, cast into A*.... i call A->a(),
this should not work since B::a is private. I think. But i am not sure
that's the way it works. Is that right?

But after B, is "a" still virtual ?
Technically, the scope of C does not have access to B::a(), and
therefore, C::a() should be a different function, with no
"relationship" with the previously overloaded virtual a?

Laurent.