strange inheritance





[23] Inheritance what your mother never told you, C++ FAQ Lite







[23] Inheritance — what your mother never told you
(Part of C++ FAQ Lite, Copyright © 1991-98, Marshall Cline, cline@parashift.com)

FAQs in section [23]:

[23.1] When my base class's constructor calls a
virtual function, why doesn't my derived class's override of that virtual
function get invoked?
[23.2] Should a derived class replace ("override") a
non-virtual function from a base class?
[23.3] What's the meaning of, Warning: Derived::f(float) hides Base::f(int)?
[23.4] What does it mean that the "virtual table" is an
unresolved external?



[23.1] When my base class's constructor calls a
virtual function, why doesn't my derived class's override of that virtual
function get invoked?
During the class Base's constructor, the object isn't yet a Derived, so
if Base::Base() calls a virtual
function virt(), the Base::virt() will be invoked, even if
Derived::virt() exists.
Similarly, during Base's destructor, the object is no longer a Derived, so
when Base::~Base() calls virt(), Base::virt() gets control,
not the Derived::virt() override.
You'll quickly see the wisdom of this approach when you imagine the disaster if
Derived::virt() touched a member object from class Derived. In
particular, if Base::Base() called the virtual function virt(),
this rule causes Base::virt() to be invoked. If it weren't for this
rule, Derived::virt() would get called before the Derived part
of a Derived object is constructed, and Derived::virt() could
touch unconstructed member objects from the Derived part of a
Derived object. That would be a disaster.
[ Top | Bottom | Previous section | Next section ]


[23.2] Should a derived class replace ("override") a
non-virtual function from a base class?
It's legal, but it ain't moral.
Experienced C++ programmers will sometimes redefine a non-virtual function
(e.g., the derived class implementation might make better use of the derived
class's resources for efficiency), or to get around the hiding
rule. However the client-visible effects must be
identical, since non-virtual functions are dispatched based on the
static type of the pointer/reference rather than the dynamic type of the
pointed-to/referenced object.
[ Top | Bottom | Previous section | Next section ]


[23.3] What's the meaning of, Warning: Derived::f(float) hides Base::f(int)?
It means you're going to die.
Here's the mess you're in: if Base declares a member function f(int), and
Derived declares a member function f(float) (same name but different
parameter types and/or constness), then the Base f(int) is "hidden" rather
than "overloaded" or "overridden" (even if the Base f(int) is
virtual).
Here's how you get out of the mess: Derived must have a using
declaration of the hidden member function. For example,

    class Base {
    public:
      void f(int);
    };
    
    class Derived : public Base {
    public:
      using Base::f;    // This un-hides Base::f(int)
      void f(double);
    };

If the using syntax isn't supported by your compiler, redefine the
hidden Base member function(s), even if they are
non-virtual. Normally this re-definition merely calls the hidden
Base member function using the :: syntax. E.g.,

    class Derived : public Base {
    public:
      void f(double);
      void f(int i) { Base::f(i); }  // The redefinition merely calls Base::f(int)
    };

[ Top | Bottom | Previous section | Next section ]


[23.4] What does it mean that the "virtual table" is an
unresolved external?
If you get a link error of the form "Error: Unresolved or undefined symbols detected: virtual table for class Fred," you probably have an undefined
virtual member function in class Fred.
The compiler typically creates a magical data structure called the "virtual
table" for classes that have virtual functions (this is how it handles
dynamic binding). Normally you don't
have to know about it at all. But if you forget to define a virtual function
for class Fred, you will sometimes get this linker error.
Here's the nitty gritty: Many compilers put this magical "virtual table" in the
compilation unit that defines the first non-inline virtual function in the
class. Thus if the first non-inline virtual function in Fred is
wilma(), the compiler will put Fred's virtual table in the same compilation
unit where it sees Fred::wilma(). Unfortunately if you accidentally
forget to define Fred::wilma(), rather than getting a
Fred::wilma() is undefined, you may get a "Fred's virtual table is
undefined". Sad but true.
[ Top | Bottom | Previous section | Next section ]


 E-mail the author
[ C++ FAQ Lite
| Table of contents
| Subject index
| About the author
| ©
| Download your own copy ]
Revised Jun 29, 1998




Wyszukiwarka

Podobne podstrony:
H P Lovecraft The Strange High House in the Mist
Btk Strangler m76
Madonna?autfiful Stranger
inherits
ABC Stranger Things
Dr Strangelove
Cooper McKenzie Strangers in the Morning (pdf)
Nieznajomi The Strangers [2008]
Surf Sea and a Sexy Stranger
Green?y Strangeland
[Strang & Strang] Spiritual thoughts, coping and sense of coherence in brain
02 Last night I had the strangest dream
Civil Strange
Lover, Stranger
Bob Shaw Ship of Strangers

więcej podobnych podstron