3

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;};
};

4 Answers 4

6

From C++ standard (section 10.3):

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, [...] then Derived::vf is also virtual (whether or not it is so declared).

So yes.

Sign up to request clarification or add additional context in comments.

Comments

6

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.

Comments

1

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
}

Comments

1
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.