Topic: Overloading (or not) Virtual functions
Author: "Matt Seitz" <mseitz@meridian-data.com>
Date: 1999/08/23 Raw View
Barry Margolin <barmar@bbnplanet.com> wrote in message
news:KTVu3.248$m84.4242@burlma1-snr2...
.. If an overloaded member function is overridden in a derived
> class (it doesn't matter whether the function is virtual or not) it
shadows
> *all* the signatures. You can't just override doit() while leaving
> doit(int) still visible in B. If you're going to override any of them,
you
>usually need to override each one
Instead of overriding each one, I would use a using-declaration, just as
Lorraine's compiler vendor suggested. Less typing, less room for errors,
and it continues to work even if more overloaded declarations are added to
the base.
---
[ 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: Barry Margolin <barmar@bbnplanet.com>
Date: 1999/08/19 Raw View
In article <37BA9FCB.DA8861A2@ed.ray.com>,
Lorraine Waldbusser <waldbuss@ed.ray.com> wrote:
>Does this make sense? Normally, a virtual function defined in a base
>class
>does not have to be defined in a derived class. Do the rules change for
>overloaded virtual functions?
Somewhat. If an overloaded member function is overridden in a derived
class (it doesn't matter whether the function is virtual or not) it shadows
*all* the signatures. You can't just override doit() while leaving
doit(int) still visible in B. If you're going to override any of them, you
usually need to override each one. Your vendor warns when you don't do
this because it's a common error.
When determining which class's member functions to use when you write
b.doit(...) or bp->doit(...), C++ first searches up the class hierarchy of
b or *bp looking for a class that defines a doit member function. Within
that class it performs overload resolution based on the parameter types.
--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
---
[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/08/19 Raw View
In article <37BA9FCB.DA8861A2@ed.ray.com>, Lorraine Waldbusser
<waldbuss@ed.ray.com> writes
>Consider the following example:
>
>class A
>{
>public:
> virtual void doit ();
> virtual void doit (int x);
>};
>
>class B: A
>{
>public:
> void doit ();
>};
were void doit(int); non virtual the over-rider to void doit() in B
would certainly hide it, and so attempts to call it via a B* or a B&
would certainly fail. Now, because it is virtual, it will appear in the
vtable (but remember that is only an implementation detail) however
name-lookup has nothing to do with vtables. doit() looked up in the
scope of B has only a single candidate.
Whenever you over-ride a member of an overload set in a derived class
you should include an appropriate using declaration unless you
explicitly want to suppress members of the overload set.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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: Lorraine Waldbusser <waldbuss@ed.ray.com>
Date: 1999/08/19 Raw View
Hopefully this is the right forum for this question...
Consider the following example:
class A
{
public:
virtual void doit ();
virtual void doit (int x);
};
class B: A
{
public:
void doit ();
};
Compiler #1 compiles this example without any warnings.
Compiler #2 gives the following warning:
overloaded virtual function "A::doit" is only partially
overridden
in class "B"
The code runs successfully with both compilers (despite the warning from
compiler 2).
When I asked the vendor of compiler 2 about this warning, I got the
following answer:
The warning is there because as Stroustrup says (C++ 3rd ed.
15.2.2)
"Overload resolution is not applied across different scopes."
What that
means is - you can't do the following:
void main(void) {
B b;
b.doit(5);
}
because the overload resolution mechanism won't look in the
scope outside
of class B to figure out which version of 'doit' to call. The
warning is
there because our compiler assumes that the user probably didn't
want to
hide any of the definitions of 'doit' from class A (which is the
case
here). To avoid the warning and to make all of the versions of
'doit'
visible in B, one could write:
class B : public A {
public:
using A::doit;
virtual void doit();
};
The 'using-declaration' will propagate all versions of 'doit' to
the
scope of class B.
Does this make sense? Normally, a virtual function defined in a base
class
does not have to be defined in a derived class. Do the rules change for
overloaded virtual functions?
--
*************************************************
* Lorraine L. Cash *
* *
* Raytheon - Software Engineering Lab *
* RAPID Laboratory *
* 528 Boston Post Road *
* Sudbury, MA 01776 *
* *
* Tel: (508)490-2574 *
* Email: Lorraine_Cash@res.raytheon.com *
*************************************************
---
[ 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: Pete Becker <petebecker@acm.org>
Date: 1999/08/19 Raw View
Lorraine Waldbusser wrote:
>
>
> Does this make sense? Normally, a virtual function defined in a base
> class
> does not have to be defined in a derived class. Do the rules change for
>
> overloaded virtual functions?
>
No, the rules don't change. That warning is part of our heritage from
cfront, and its wording is very misleading. The potential problem that
it points out occurs even when the functions aren't virtual:
B b;
b.doit(3); // illegal: no version of doit in B takes an int
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
[ 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: Jeff Rife <jrifeSPAM@BEnabsGONE.net>
Date: 1999/08/19 Raw View
Lorraine Waldbusser (waldbuss@ed.ray.com) wrote:
> Consider the following example:
[snip]
> void main(void) {
<standard correction>
Well, you don't want to do void main() anyway. main returns an int.
</standard correction>
> B b;
> b.doit(5);
> }
The whole point of virtual functions is to use pointers, to gain
polymorphism. In particular, you use a pointer to the base class, so
that you can then call *at run time* the function from the class that
the pointer is *really* pointing to.
By having an object and not a pointer, you lose the polymorphism, and
all functions called are B functions, because the compiler absolutely
knows that the static *and* dynamic type of b is B.
B doesn't have a function doit(int), and B::doit() hides all like-named
fucntions in all base classes. Thus, the problem.
This "hiding" occurs whether or not the functions are virtual.
> Compiler #1 compiles this example without any warnings.
> Compiler #2 gives the following warning:
>
> overloaded virtual function "A::doit" is only partially
> overridden
> in class "B"
>
> The code runs successfully with both compilers (despite the warning from
> compiler 2).
Now, why it runs successfully has to do with the fact that the functions
are virtual (it wouldn't if they were not).
The vtable for A looks something like:
+--------------------------------+
| void doit() ==> A::doit() |
| void doit(int) ==> A::doit(int)|
+--------------------------------+
B inherits this vtable, changes pointers for overridden functions:
+--------------------------------+
| void doit() ==> B::doit() |
| void doit(int) ==> A::doit(int)|
+--------------------------------+
and then appends virtual functions that don't exist in A:
+--------------------------------+
| void doit() ==> B::doit() |
| void doit(int) ==> A::doit(int)|
+--------------------------------+
+--------------------------------+
There are none, so nothing is actually added.
I don't however, know if it *should* work, according to the standard,
and it won't work on some compilers, as they don't use the vtable to
dispatch static-typed functions.
--
Jeff Rife |
19445 Saint Johnsbury Lane | http://www.nabs.net/Cartoons/Dilbert/MoneyNotDogs.gif
Germantown, MD 20876-1610 |
Home: 301-916-8131 |
Work: 301-770-5800 Ext 5335 |
[ 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 ]