典型的工厂设计模式要求基类声明虚拟析构函数,但实际上可以使用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的静态类型来调用,并且您不希望在多态类中使用它。