How to force only smart pointers instance for a class?

后端 未结 2 1811
庸人自扰
庸人自扰 2021-02-04 10:53

I\'ve been working on a way to prevent user of using a class without smart pointers. Thus, forcing them to have the object being heap allocated and managed by smart pointers. In

相关标签:
2条回答
  • 2021-02-04 11:14

    As there is no general term "smart pointer" what you want is not possible.

    What you can do, is supporting some known set of smart pointers. The usual solution starts as yours, making ctor or dtor private, and adds factory functions. That can return the instance packed with your desired smart pointers. If you just want to support unique_ptr and shared_ptr, that meaans two factory functions, hardly too much. (note that those pointers allow smuggling out the raw pointer through simple interface so the control is not full.)

    0 讨论(0)
  • 2021-02-04 11:26

    Create a friend'd factory function that returns a std::unique_ptr<A>, and make your class have no accessible constructors. But make the destructor available:

    #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)...));
        }
    };
    

    Now your clients can obviously get a unique_ptr<A>:

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

    But your clients can just as easily get a shared_ptr<A>:

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

    Because std::shared_ptr can be constructed from a std::unique_ptr. And if you have any user-written smart pointers, all they have to do to be interoperable with your system is create a constructor that takes a std::unique_ptr, just like std::shared_ptr has, and this is very easy to do:

    template <class T>
    class my_smart_ptr
    {
        T* ptr_;
    public:
        my_smart_ptr(std::unique_ptr<T> p)
            : ptr_(p.release())
        {
        }
        // ...
    };
    
    0 讨论(0)
提交回复
热议问题