如何重载static和dynamic_point_cast

How to overload static and dynamic_pointer_cast

本文关键字:dynamic point cast static 何重载 重载      更新时间:2023-10-16

我有一个像下面这样的智能指针类:

template <class T>
class Sptr {
    template<typename U> friend class Sptr;
    template <typename T1, typename T2>
    friend bool operator==(const Sptr<T1> &a, const Sptr<T2> &b);
private:
    T* obj;//pointer to current obj
    RC* ref; //reference counter
    std::function<void()> destroyData;
    bool ok_;
public:
    Sptr();
    ~Sptr();
    template <typename U> 
    Sptr(U *);
    Sptr(const Sptr &);
    template <typename U> 
    Sptr(const Sptr<U> &);
    template <typename U> 
    Sptr<T> &operator=(const Sptr<U> &);
    Sptr<T> &operator=(const Sptr<T> &);
    void reset();
    T* operator->() const
    {return obj;};
    T& operator*() const
    {return *obj;};
    T* get() const
    {return obj;};
    explicit operator bool() const {
          return ok_;
    }

};

到现在为止一切都很好,我想写static_pointer_castdynamic_pointer_cast的函数。我不知道该如何继续下去。谁能给我指个正确的方向?下面是一个示例测试代码,我打算通过它来测试它。(c++11件事ok)

// Test static_pointer_cast.
{
    Sptr<Derived> sp(new Derived);
    Sptr<Base1> sp2(sp);
    Sptr<Derived> sp3(static_pointer_cast<Derived>(sp2));
}
// Test dynamic_pointer_cast.
{
    Sptr<Derived_polymorphic> sp(new Derived_polymorphic);
    Sptr<Base_polymorphic> sp2(sp);
    Sptr<Derived_polymorphic> sp3(dynamic_pointer_cast<Derived_polymorphic>(sp2));
    Sptr<Derived_polymorphic> sp4(static_pointer_cast<Derived_polymorphic>(sp2));
    Sptr<Derived2_polymorphic> sp5(dynamic_pointer_cast<Derived2_polymorphic>(sp2));
    assert(!sp5);
}

两个类型转换都是模板(可能是友型),它们创建了一个不同类型的新Sptr,并通过对底层指针的类型转换初始化,并根据需要增加引用计数。主要的复杂之处在于,您需要指向同一个完整对象的不同类型的多个指针,并且当最后一个指针(无论其类型是什么)超出作用域时,您需要管理使用正确指针调用deleter。

一种可能的方法是将删除指针和原始指针存储在引用计数对象中(顺便说一句,删除指针应该一直在那里,你只需要一个副本!)。每个Sptr都持有不同类型的原始指针,但是当它消失时,它会使用存储在引用计数中的指针。