我想对几个班级实施shared_ptr
。我正在使用static
工厂函数来封装私有构造函数:
#include <memory>
class MyClass
{
public:
static std::shared_ptr<MyClass> create() {
auto a = std::shared_ptr<MyClass>(new MyClass());
return a;
}
private:
MyClass();
~MyClass();
}
}
此模板在VS2017
中以C2440
(函数样式转换)失败,但在VS2015
中工作正常,我也不知道为什么。 make_shared-version在这两种版本中都可以正常工作,但需要公共构造函数。
知道我缺少哪个选项吗?
答案 0 :(得分:2)
好像VS2017抱怨从std::shared_ptr
访问析构函数,因此您可能想将std::shared_ptr
声明为MyClass的朋友。对于std::make_shared
,您可以使用此答案How do I call ::std::make_shared on a class with only protected or private constructors?
class MyClass
{
public:
static std::shared_ptr<MyClass> create() {
struct make_shared_enabler : MyClass {};
return std::make_shared<make_shared_enabler>();
}
// compiles fine for gcc without friend though
//friend class std::shared_ptr<MyClass>;
private:
MyClass() {}
~MyClass() {}
};
答案 1 :(得分:1)
除了其他答案:如果您不想将std::shared_ptr
声明为班级的朋友,并且不想将析构函数公开,则可以使用以下方法创建shared_ptr
自定义删除器。为此,您将需要MyClass
中的某些方法可以访问私有析构函数并调用delete
。例如:
class MyClass
{
public:
static std::shared_ptr<MyClass> create() {
auto a = std::shared_ptr<MyClass>(new MyClass(),
[](MyClass* ptr) { destroy(ptr); });
return a;
}
static void destroy(MyClass* ptr) { delete ptr; }
private:
MyClass(){}
~MyClass(){}
};
// later in the source code
auto ptr = MyClass::create();
您还可以将destroy
方法声明为非静态方法,并在内部自杀(这种情况实际上是有实际意义的几种情况之一)。