Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ shared_ptr in polymorphism without virtual destructor

A typical factory design pattern require the base class to declare virtual destructor, but this can be actually avoided using shared_ptr.

#include <iostream>
#include <memory>
#include <cstdio>

using namespace std;

class Dog {
  public:
  ~Dog() { cout << "dog destroyed\n"; }
};

class Yellowdog : public Dog {
  public:
  ~Yellowdog() { cout << "Yellow dog destroyed.\n"; }
};

class DogFactory {
  public:
  static shared_ptr<Dog> createYellowdog() { 
    return shared_ptr<Yellowdog>(new Yellowdog()); 
  }
};

int main(int argc, char *argv[]) {

  auto ptr = DogFactory::createYellowdog();
  cout << ptr.use_count() << endl;

  return 0;
}

In this case the output is yellowdog destroyed followed by dog destroyed. But why? Why using shared_ptr can omit the virtual keyword before ~Dog?

like image 664
Jes Avatar asked Jul 27 '26 01:07

Jes


1 Answers

This is happening because shared_ptr stores type-erased deleter in the control block, which is created when the first shared_ptr is created. In your case shared_ptr is created for yellow dog, and deleter is to call yellow-dog destructor.

When you copy (or copy-construct) one shared_ptr to another, they share the same control block, and new shared ptr is going to call deleter from the original one - the one which will call yellowdog destructor.

However, it doesn't really make the class polymorphic and suitable for factory implementation - any other non-virtual function in the class will be called based on static type of shared_ptr, and you do not want this in polymorphic classes.

like image 194
SergeyA Avatar answered Jul 29 '26 18:07

SergeyA



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!