0

I have a purely abstract class:

class Abstract{
     void func1(arg1, arg2) = 0;
}

And its implementation with a destructor:

class Concrete : public Abstract{
void func1(arg1,arg2) { /*implementation code..*/ };
~Concrete() {/*code for the destructor..*/}

In main.cpp I create an unique pointer for it:

 int main(){
 std::unique_ptr<Abstract> class = std::make_unique<Concrete>();
 //do operations with it
 class.reset();
 }

After I'm done with class I need it to call the (custom) destructor of its current implementation class, but .reset() doesn't do that. How do I call the destructor of this implementation of Abstract class?

  • 1
    You need to declare and define a virtual destructor on the base class. It may be empty but it needs to be present so that on destruction, the proper destructor can be found and called. https://stackoverflow.com/questions/270917/why-should-i-declare-a-virtual-destructor-for-an-abstract-class-in-c – ypnos May 10 '20 at 08:37
  • And then `.reset()` will work? –  May 10 '20 at 08:41
  • Reset leads to regular destruction of the object. If an object has a virtual destructor, this will lead to the derived destructor to be called. So in short, yes. – ypnos May 10 '20 at 08:42
  • If you can replace `unique_ptr` with `shared_ptr`, you won't need a virtual destructor in `Abstract`. – Evg May 10 '20 at 08:56
  • 1
    @Evg that's true but I would consider it bad design if you don't have a protected/private destructor in the base class. Also I would not make this a reason to choose between `unique_ptr` and `shared_ptr` as they have different purposes. – ypnos May 10 '20 at 08:59
  • 1
    Shouldn't `Concrete` inherit from `Abstract`? – Daniel Langr May 10 '20 at 09:01

1 Answers1

1

As per your implementation you have not defined your Abstract Class Destructor as virtual.

So simple fix will be to make the destructor of the Abstract Class as virtual.

So the Declaration of the Abstract Class will look like below:

class Abstract{
     public:
     void func1(arg1, arg2) = 0;
     virtual ~Abstract() {/*..Destrctor Body..*/}
}

Now coming for the reason since in main.cpp , you are pointing to an object of Concrete Class using pointer of the Abstract Class and as you've performed reset() on the pointer of the Abstract class , it will cause the destructor of only Abstract class to be envoked.

But as soon as you've made the destructor of the Abstract Class as Virtual , it will call the **destructor of the Concrete Class **First**** and then later the destructor of the Abstract Class will be called.

For further details I am sharing one thread for the reference When Should we Use Virtual keyword ?

user207421
  • 305,947
  • 44
  • 307
  • 483
Chandra Shekhar
  • 598
  • 1
  • 7
  • 25
  • Re: "... it will cause the destructor of only Abstract class to be invoked" -- it's worse than that. The behavior is undefined. The language definition does not impose any requirements on what that code does. In practice, you're right, but compilers aren't required to do that. +1. – Pete Becker May 10 '20 at 12:56