使用私有析构函数创建仅shared_ptr的类?

Cha*_*nya 1 c++ shared-ptr c++20

我有一个在线程之间传递的数据类。我希望这个类成为std::shared_ptr唯一一个不能通过从外部调用其析构函数来销毁的类,因此我也希望析构函数是私有的。我目前的解决方案是

template<typename T>
struct DestructorHelper
{
    static void Destroy(void* v) { delete static_cast<T*>(v); }
};

class SharedOnly
{
public:
    SharedOnly(const SharedOnly& other) = delete; // deleted copy constructor
    SharedOnly& operator=(const SharedOnly& other) = delete; // deleted copy assignment operator
    SharedOnly(SharedOnly&& other) = delete; // deleted move constructor
    SharedOnly& operator=(SharedOnly&& other) = delete; // deleted move assignment operator

    static std::shared_ptr<SharedOnly> create()
    {
        auto objPtr = new SharedOnly;
        auto desPtr = &DestructorHelper<SharedOnly>::Destroy;
        std::shared_ptr<SharedOnly> shared(objPtr, desPtr);
        return shared;
    }

private:
    SharedOnly() = default;
    ~SharedOnly() = default;
    friend struct DestructorHelper<SharedOnly>;
};
Run Code Online (Sandbox Code Playgroud)

有什么办法可以让我在没有 的情况下上这门课DestructorHelper吗?我正在寻找的是一个优雅的解决方案来创建一个std::shared_ptr唯一的类,以便它可以传递给不同的线程,并且仅当指向该对象的最后一个共享指针被销毁时才被销毁。

Que*_*tin 5

您可以使用 lambda 来解析内部的析构函数访问create

static std::shared_ptr<SharedOnly> create()
{
    return {new SharedOnly, [](SharedOnly *const s) { delete s; }};
}
Run Code Online (Sandbox Code Playgroud)

  • @Chaitanya它的工作原理是一样的,但我没有一个原始的拥有指针来担心并确保异常安全。事实上,我只是搞砸了:`std::shared_ptr` 的构造函数被指定为在发生异常时`删除`其参数,所以我的 `try`/`catch` 会双重删除...:)编辑:这意味着“unique_ptr”毕竟是无用的。那好吧。 (2认同)