13

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

#include <memory>
class A
{
private :
    ~A {}
    // To force use of A only with std::unique_ptr
    friend std::default_delete<A>;
};

如果您只希望您的类用户能够通过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>;
};

但是这个解决方案是不可移植的。也许我做错了。

4

2 回答 2

19

创建一个返回 a 的友元工厂函数,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)...));
    }
};

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

std::unique_ptr<A> p1 = make_A();

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

std::shared_ptr<A> p2 = make_A();

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

template <class T>
class my_smart_ptr
{
    T* ptr_;
public:
    my_smart_ptr(std::unique_ptr<T> p)
        : ptr_(p.release())
    {
    }
    // ...
};
于 2013-06-16T16:48:55.260 回答
0

由于没有通用术语“智能指针”,您想要的东西是不可能的。

您可以做的是支持一些已知的智能指针集。通常的解决方案从您的开始,将 ctor 或 dtor 设为私有,并添加工厂函数。这可以返回包含所需智能指针的实例。如果你只想支持 unique_ptr 和 shared_ptr,这意味着两个工厂函数,几乎没有太多。(请注意,这些指针允许通过简单的接口将原始指针走私出来,因此控件未满。)

于 2013-06-16T16:19:08.937 回答