Reputation: 1527
I have a question about the following code:
#include <iostream>
#include <boost/scoped_ptr.hpp>
class Interface
{
};
class A : public Interface
{
public:
A() { std::cout << "A()" << std::endl; }
virtual ~A() { std::cout << "~A()" << std::endl; }
};
Interface* get_a()
{
A* a = new A;
return a;
}
int main()
{
{
std::cout << "1" << std::endl;
boost::scoped_ptr<Interface> x(get_a());
std::cout << "2" << std::endl;
}
std::cout << "3" << std::endl;
}
It creates the following output:
1
A()
2
3
As you can see, it doesn't call the destructor of A. The only way I see to get the destructor of A being called, is to add a destructor for the Interface class like this:
virtual ~Interface() { }
But I really want to avoid any Implementation in my Interface class and virtual ~Interface() = 0;
doesn't work (produces some linker errors complaining about a non existing implementation of ~Interface()
.
So my question is: What do I have to change in order to make the destructor being called, but (if possible) leave the Interface as an Interface (only abstract methods).
Upvotes: 2
Views: 1008
Reputation: 503825
You must define a virtual destructor in the base class, otherwise you'll get no polymorphic behavior.
And more importantly, you get undefined behavior otherwise; §5.3.5/3:
If the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined.
Emphasis mine.
I'd argue the best is this one:
class Interface
{
public:
virtual ~Interface(void) = 0;
};
inline Interface::~Interface(void) {}
The compiler can easily inline this, unlike a solution where the implementation resides in a source file. (Speaking of which, this solution doesn't even mandate you have one.) It also leaves the class pure virtual.
Upvotes: 5
Reputation: 355049
You must declare the destructor virtual
if you want to delete derived-class objects via a pointer to your base class interface type, and that destructor must have an implementation.
You may still declare it pure virtual, though:
class Interface
{
public:
virtual ~Interface() = 0;
};
inline Interface::~Interface() { }
Upvotes: 2
Reputation: 20609
You need to define a pure virtual version of the Interface destructor, but you need to also define the body of the destructor. This is a sort of weird case in C++ where even though the function is virtual it must be defined because after the A destructor is called, the Instance destructor will also be called.
Thus the correct answer is:
virtual ~Interface() = 0;
And later, in a cpp file:
Interface::~Interface() {}
Upvotes: 2