Is it OK to inherit from the C++11 smart pointers and override the relative operators?

前端 未结 3 2067
野性不改
野性不改 2021-02-18 21:27

According to cppreference.com, std::shared_ptr provides a full set of relative operators (==, !=, <, ...), but the semantics of comparison aren\'t specified. I a

3条回答
  •  甜味超标
    2021-02-18 21:51

    In general, it's not safe to inherit from anything who's destructor is not dynamic. It can be and is done commonly, you just have to be really careful. Instead of inheriting from the pointers, I'd just use composition, especially since the number of members is relatively small. You might be able to make a template class for this

    template
    class relative_ptr {
    public:
        typedef typename std::pointer_traits::pointer pointer;
        typedef typename std::pointer_traits::element_type element_type;
        relative_ptr():ptr() {}
        template
        relative_ptr(U&& u):ptr(std::forward(u)) {}
        relative_ptr(relative_ptr&& rhs):ptr(std::move(rhs.ptr)) {}
        relative_ptr(const relative_ptr& rhs):ptr(std::move(rhs.ptr)) {}
    
        void swap (relative_ptr& rhs) {ptr.swap(rhs.ptr);}
        pointer release() {return ptr.release();}
        void reset(pointer p = pointer()) {ptr.reset(p);}
        pointer get() const {return ptr.get();}
        element_type& operator*() const {return *ptr;}
        const pointer_type& operator->() const {return ptr;}
    
        friend bool operator< (const relative_ptr& khs, const relative_ptr& rhs) const 
        {return std::less(*lhs,*rhs);}
        friend bool operator<=(const relative_ptr& khs, const relative_ptr& rhs) const 
        {return std::less_equal(*lhs,*rhs);}
        friend bool operator> (const relative_ptr& khs, const relative_ptr& rhs) const 
        {return std::greater(*lhs,*rhs);}
        friend bool operator>=(const relative_ptr& khs, const relative_ptr& rhs) const 
        {return std::greater_equal(*lhs,*rhs);}
        friend bool operator==(const relative_ptr& khs, const relative_ptr& rhs) const 
        {return *lhs==*rhs;}
        friend bool operator!=(const relative_ptr& khs, const relative_ptr& rhs) const 
        {return *lhs!=*rhs;}
    protected:
        pointer_type ptr;
    };
    

    Obviously, the simplicity of the wrapper reduces you to the lowest common denominator for the smart pointers, but whatever. They're not exactly complicated, you could make one for each of the smart pointer classes.

    I will provide a warning that I don't like the way == works, since it may return true for two pointers to different objects. But whatever. I also haven't tested the code, it might fail for certain tasks, like attempting to copy when it contains a unique_ptr.

提交回复
热议问题