Will the compiler-generated destructor of an abstract base class be virtual?
Asked Answered
O

4

7
class Base
{
    virtual void foo() = 0;
    //~Base();     <-- No destructor!
};

Obviously, Base will be derived. So, does C++ says the compiler-generated destructor of Base must be virtual?

Thanks!

Octavo answered 12/8, 2011 at 14:51 Comment(2)
No. But I can't give you a reference for something the standard doesn't say...Faery
If only compilers could answer questions on stackoverflow ;)Quahog
B
8

No, the destructor will not be virtual unless you mark it as such. The reason is simple - calls can be made virtually both via pointers and via references and how and whether you make calls virtually is unrelated to whether you create objects with new. If you don't create objects with new you don't have to delete them and so you don't need virtual destructors.

Bandwidth answered 12/8, 2011 at 14:56 Comment(0)
F
2

It does not. This is close to a proof that the destructor is not automatically made virtual:

#include <iostream>

struct BaseBase {
    ~BaseBase() {
        std::cout << "~BaseBase\n";
    }
};

struct Base : BaseBase
{
    virtual void foo() = 0;
    //~Base();     <-- No destructor!
};

struct Derived : Base {
    void foo() { std::cout << "foo\n"; }
    ~Derived() {
        std::cout << "~Derived\n";
    }
};

int main() {
    Base *p = new Derived();
    delete p;
}

This program actually has undefined behavior, but I strongly suspect that on your implementation it does not print "~Derived". If Base had a virtual destructor, then it would not have undefined behavior, and it would print "~Derived".

Of course it doesn't actually prove anything about the standard. Any implementation you run it on might after all be non-conforming. But once you've tried it on a few, you'll get the idea that whatever the standard might say, you need to specify a virtual destructor.

Faery answered 12/8, 2011 at 15:1 Comment(1)
I tested in codepad: codepad.org/oMs4Kuye (g++ 4.1.2) and it does not print "~Derived" as you expected. Neither on my MSVC2008. Thanks for the example.Octavo
H
1

No, the dtor is not guaranteed to be virtual.

When declaring classes specifically designed to be derived from, its good practice to explicitly declare a virtual dtor. It's typically an outright design flaw not to. In fact, I can't think of a case where its not a design flaw to omit the virtual dtor from the base class.

Headdress answered 12/8, 2011 at 14:58 Comment(4)
Some classes can be designed to be derived from but not used polymorphically (for instance, boost::noncopyable). In this case, there is no point in providing a virtual destructor.Guilder
@Luc: in that case, it's a good idea to make the base class destructor protected, to prevent invalid polymorphic deletion.Interposition
Well that's true of course. I was thinking in terms of the question's context, which was an ABC.Headdress
I've seen rahter large code-base with no virtual destructors at all, although there were abstract bases. The trick is that smart pointers deleted objects only using original pointer, so everything just works and you have one less thing (virtual dtor) to care about.Calamine
A
1

No. A class can have virtual members, can be derived and can even be allocated with new and deleted with delete without having a virtual destructor.

What is illegal (UB) to do is to destroy a derived instance with delete using a pointer to base if the destructor is not declared virtual.

Of course there are no reason at all for not declaring a virtual destructor if your class is meant to be derived.

Airline answered 12/8, 2011 at 15:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.