如何阻止使用std :: make_shared <T>

mar*_*964 3 c++ class shared-ptr make-shared c++14

我知道我可以通过将自定义类及其后代operator new设为私有来防止普通堆分配,但是有什么方法可以防止库的用户调用std::make_shared自定义类(或其后代)?显然,仅使operator new私有成为类并不能阻止它。

请注意,我不想完全阻止以任何方式创建共享指针,因为我打算仍然能够std::shared_ptr通过调用静态生成器方法来为自定义类生成一个,但是我仍然想防止其他人尝试调用std::make_shared直接在我的课上。

编辑:

为了解决下面的查询,我的最终目标是从原始指针中提取shared_ptr的灵活且可重用的机制。std::enable_shared_from_this遗憾的是,在继承方面,尤其是在多重继承方面,它不是很友好。

另外,因为我打算将此作为在使用CRTP的模板类中使用,所以子类T需要显式地使它继承自朋友的模板化父类使其变得可以访问,这会使事情复杂化。私有构造函数。

sup*_*per 6

这不是特定于的std::shared_ptr,但您可以将构造函数设为私有,这样可以强制从静态方法生成类的所有实例。

#include <iostream>
#include <memory>

class Foo {
    private:
    Foo() = default;

    public:
    static std::shared_ptr<Foo> make() {
        return std::shared_ptr<Foo>(new Foo);
    }
};

int main() {
    //Foo f1;
    //auto f2 = std::make_shared<Foo>(); 
    //above does not work since the constructor is private
    auto h = Foo::make();
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用重复数据删除器建议并使用私钥来使构造函数在类外部不可访问。

#include <iostream>
#include <memory>

class Foo {
    private:
    struct FooKey {};

    public:
    Foo(FooKey) {};

    static std::shared_ptr<Foo> make() {
        return std::make_shared<Foo>(FooKey{});
    }
};

int main() {
    //Foo f1{Foo::FooKey{}};
    //auto f2 = std::make_shared<Foo>(Foo::FooKey{}); 
    //above does not work since Foo::FooKey is private
    auto h = Foo::make();
}
Run Code Online (Sandbox Code Playgroud)