典型的工厂设计模式要求基类声明虚拟析构函数,但实际上可以使用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;
}

在这种情况下,输出为yellowdog destroyed后跟dog destroyed。但为什么?为什么使用shared_ptr可以在~Dog之前省略虚拟关键字?

最佳答案

发生这种情况是因为shared_ptr在控制块中存储了类型删除的删除程序,该删除程序是在创建第一个shared_ptr时创建的。在您的情况下,为黄狗创建了shared_ptr,而deleter则调用了黄狗析构函数。

当您将一个shared_ptr复制(或复制构造)到另一个shared_ptr时,它们共享相同的控制块,并且新的共享ptr将从原始的ptr调用deleter-一个将称为yellowdog析构函数的代码。

但是,它并不能真正使该类成为多态的并且不适合工厂实现-该类中的任何其他非虚函数都将基于ojit_code的静态类型来调用,并且您不希望在多态类中使用它。

09-11 17:32