c++ - 如何仅强制类的智能指针实例?

标签 c++ c++11 class-design smart-pointers

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

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

如果您只希望您的类(class)用户能够通过 std::unique_ptr 操作您的类(class)的实例,这将非常有效。 .但它不适用于 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>;
};

但此解决方案不可移植。也许我做错了。

最佳答案

创建一个返回 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 构造.如果您有任何用户编写的智能指针,它们要与您的系统互操作所需要做的就是创建一个构造函数,该构造函数采用 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())
    {
    }
    // ...
};

关于c++ - 如何仅强制类的智能指针实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17134925/

相关文章:

java - 最佳实践 : instance variables filling over time

c# - c# 类应该生成自身的实例吗?

c++ - 从临时返回常量对象和构造

c++ - 使用指针交换整数

c++ - 如果锁定,mongodb upsert 不会更新

c++ - 在转换构造函数上启用_if(静态转换,is_base_of)

c++ - 使用单例分配静态成员

c++ - Rcpp 生成变量 : portable -mpopcnt flag

javascript - 面向对象的Javascript : good way to combine prototypal inheritance with private vars?

c++ - 无法从 C++ 中的函数捕获异常