Search code examples
c++c++20shared-ptr

Creating shared_ptr only class with private destructor?


I have a data class that is passed between threads. I would like this class to be a std::shared_ptr only class that cannot be destroyed by calling its destructor from outside and so I want the destructor to be private as well. My current solution is

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>;
};

Is there any way I could make this class without the DestructorHelper? What I am looking for is an elegant solution to make a std::shared_ptr only class so that it can be passed around to different threads and is only destroyed when the last shared pointer pointing to the object is destroyed.


Solution

  • You can use a lambda to resolve the destructor access from within create:

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