问题
I have the following class hierarchy.
class A {
public:
virtual bool foo() const;
};
class B : public A {
// Redeclare foo as virtual here?
};
class C : public B {
bool foo() const {/*Definition*/ return true;}
};
class D : public B {
bool foo() const {/*Definition*/ return false;}
};
So the foo() method the class C and D wants to implement, B doesn't. How can I achieve that? Do I have to re-declare the foo() as virtual in class B?
Note: Ignore minor syntactical error here and there. This is not actual code. My question is only about the concept.
回答1:
If you strictly want a derived class to implement a function then make the function as
pure virtual function
in the base class.If you just want random derived class to reimplment a function then simply make the function
virtual
in the base class, which you did in your example.
Now, since function foo
is virtual
in base class A
so a virtual table vtable
will be create for class A
and all the classes derived directly or indirectly from class A
.
Virtual Function entry are stored in vtable
and they just get replaced in vtable
if they are reimplemented in the subsequent derived classes.
- So, if
class B
reimplementsfoo
then invtable
ofclass B
the entry will beB::foo
. - So, if
class C
reimplementsfoo
then invtable
ofclass C
the entry will beC::foo
.
So, class B
is not required to declare function foo
as virtual
.
If a function is virtual
then resolution will happen at run time using the vtable
of the corresponding class whose object is used.
回答2:
The answer is no, B does not have to re-implement foo(). It has inherited the function from A. Note that if you create a (stack-allocated) instance of B and call foo()
on it, then the function is not treated as virtual--A's foo()
is called.
To use the redefined virtual verson of a function in a derived class (take advantage of polymorphism see), you must call the function via a pointer or reference to an instance of the derived class. Otherwise the static type of the object will be used.
B b;
B.foo(); // calls A's foo()
B* b_ptr = &b;
b_ptr->foo(); // calls B's foo()
B& b_ref = b;
b_ref.foo(); // calls B's foo()
来源:https://stackoverflow.com/questions/41604948/not-defining-virtual-method-in-derived-class-as-well