问题
Say we have the following two classes, A is the base class with virtual destructor and B is the derived class whose destructor doesn't have 'virtual' qualifier. My question is, if I going to derive more classes from B, will B's destructor automatically inherit the virtualness or I need to explicitly put 'virtual' before '~B() {...}'
class A
{
public:
A() { std::cout << "create A" << std::endl;};
virtual ~A() { std::cout << "destroy A" << std::endl;};
};
class B: A
{
public:
B() { std::cout << "create B" << std::endl;};
~B() { std::cout << "destroy B" << std::endl;};
};
回答1:
From C++ standard (section 10.3):
If a virtual member function
vf
is declared in a classBase
and in a classDerived
, derived directly or indirectly fromBase
, [...] thenDerived::vf
is also virtual (whether or not it is so declared).
So yes.
回答2:
If base class method is virtual
then all the subsequent derived class methods will become virtual
. However, IMO it's a good programming practice to put virtual
ahead of the method; just to indicate the reader the nature of the function.
Also note that there are some corner case where you might get unexpected results:
struct A {
virtual void foo(int i, float f) {}
};
sturct B : A {
void foo(int i, int f) {}
};
Here actually, B::foo()
is not overriding A::foo()
with virtual
mechanism; rather it's hiding it. So irrespective of you make B::foo()
virtual, there is no advantage.
In C++0x, you have override keyword, which overcomes such problems.
回答3:
Virtualness is inherited all the way down. You only need to specify it in the top base class.
This is true for destructors as well as normal member functions.
Example:
class Base { virtual void foo() { std::cout << "Base\n"; } };
class Derived1 : public Base { void foo() { std::cout << "Derived1\n"; } };
class Dervied2 : public Derived1 { void foo() { std::cout << "Derived2\n"; } };
int main()
{
Base* b = new Base;
Base* d1 = new Derived1;
Base* d2 = new Derived2;
Derived1* d3 = new Derived2;
b->foo(); // Base
d1->foo(); // Derived1
d2->foo(); // Derived2
d3->foo(); // Derived2
}
回答4:
or I need to explicitly put 'virtual' before '~B() {...}'
No, you need not, although you can put virtual here to make code more clear for the reader. This applies not only for destructors but for all member functions.
来源:https://stackoverflow.com/questions/6813624/does-derived-class-member-functions-inherit-virtualness-from-base-class