如何只强制类的智能指针实例?

Nem*_*olh 12 c++ class-design smart-pointers c++11

我一直在努力防止用户使用没有智能指针的类.因此,强制它们使对象被智能指针分配和管理.为了得到这样的结果,我尝试了以下方法:

#include <memory>
class A
{
private :
    ~A {}
    // To force use of A only with std::unique_ptr
    friend std::default_delete<A>;
};
Run Code Online (Sandbox Code Playgroud)

如果您只希望您的类用户能够通过操作类的实例,那么这项工作非常好std::unique_ptr.但它不起作用std::shared_ptr.所以我想知道你是否有任何想法来获得这样的行为.我发现的唯一解决方案是执行以下操作(使用friend std::allocator_traits<A>;效率不高):

#include <memory>
class A
{
private :
    ~A {}
    // For std::shared_ptr use with g++
    friend __gnu_cxx::new_allocator<A>;
};
Run Code Online (Sandbox Code Playgroud)

但这种解决方案不可移植.也许我做错了.

How*_*ant 17

创建一个返回a的friend'd工厂函数,std::unique_ptr<A>并使您的类没有可访问的构造函数.但是要使析构函数可用:

#include <memory>

class A;

template <class ...Args>
std::unique_ptr<A> make_A(Args&& ...args);

class A
{
public:
    ~A() = default;
private :
    A() = default;
    A(const A&) = delete;
    A& operator=(const A&) = delete;

    template <class ...Args>
    friend std::unique_ptr<A> make_A(Args&& ...args)
    {
        return std::unique_ptr<A>(new A(std::forward<Args>(args)...));
    }
};
Run Code Online (Sandbox Code Playgroud)

现在您的客户显然可以获得unique_ptr<A>:

std::unique_ptr<A> p1 = make_A();
Run Code Online (Sandbox Code Playgroud)

但是您的客户可以轻松获得shared_ptr<A>:

std::shared_ptr<A> p2 = make_A();
Run Code Online (Sandbox Code Playgroud)

因为std::shared_ptr可以从一个构造std::unique_ptr.如果你有任何用户编写的智能指针,他们所需做的只是与你的系统互操作就是创建一个构造函数,std::unique_ptr就像std::shared_ptr有一样,这很容易做到:

template <class T>
class my_smart_ptr
{
    T* ptr_;
public:
    my_smart_ptr(std::unique_ptr<T> p)
        : ptr_(p.release())
    {
    }
    // ...
};
Run Code Online (Sandbox Code Playgroud)

  • 当有更多类`B`,`C`等等,并且需要这样一个`make_B()`,`make_C()`工厂函数的公共接口时,我倾向于更喜欢静态公共成员模板`T :: make( )`.这使得设置一个完整的工厂+注册表类变得容易一些,其中具体的类型`make()`函数可以在编译时从类型列表中注册. (4认同)