2013-04-17 2 views
1

У меня есть смарт-класс указателя, как показано ниже:Как перегрузить статические и dynamic_pointer_cast

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_cast и dynamic_pointer_cast. Я не знаю, как двигаться дальше. Может ли кто-нибудь направить меня в правильном направлении. Ниже приведен пример тестового кода, который я намерен передать inorder для его проверки. (C++ 11 вещей ок)

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

ответ

0

Обе слепки шаблонов (вероятно, друзья), которые создают новый Sptr другого типа инициализируется с броском в основной указатель и увеличивают счетчик ссылок по мере необходимости. Основное усложнение заключается в том, что вам нужно несколько указателей разных типов для одного и того же полного объекта, и вам нужно управлять вызовом делетера с правильным указателем, когда последний из (какой бы он ни был) выходит за рамки.

Возможный подход заключается в хранении делетера и исходного указателя внутри объекта подсчета ссылок (кстати, дебетер всегда должен был быть там, вам нужна только одна копия!). Каждый Sptr содержит необработанный указатель разных типов, но когда он уходит, он использует указатель, хранящийся в счетчике ссылок, с делетером.

Смежные вопросы