2013-04-08 73 views
-1

我實現了一個基本的智能指針類。它適用於以下類型的代碼。 (考慮了基礎1的公共構造)通過指針刪除派生,而不是基地

Sptr<Base1> b(new Base1); 
b->myFunc(); 
{ 
    Sptr<Base1> c = b; 
    Sptr<Base1> d(b); 
    Sptr<Base1> e; 
    e = b; 
} 

但在測試代碼它有一個受保護的構造(我需要它是這樣)。和代碼

Sptr<Base1> sp(new Derived); 

產生以下錯誤(注意派生):

Sptr.cpp: In instantiation of ‘my::Sptr<T>::~Sptr() [with T = Base1]’: 
Sptr.cpp:254:39: required from here 
Sptr.cpp:205:9: error: ‘Base1::~Base1()’ is protected 
Sptr.cpp:97:17: error: within this context 

問題是我必須確保你通過一個指向派生,而不是刪除基礎1。我怎樣才能做到這一點?

下面是類代碼(夾在顯示的構造和析構函數和類成員)

template <class T> 
class Sptr { 
private: 
    T* obj; // The actual object pointed by 
     RC* ref;// A reference object to keep track of count 
public: 
    //declarations 


template <typename T> 
Sptr<T>::Sptr():obj(NULL),ref(NULL) { 
    //do something 
    std::cout<<"()\n"; 
    ref = new RC(); 
    ref->AddRef(); 
} 

template <typename T> 
Sptr<T>::Sptr(const Sptr &a) : obj(a.obj),ref(a.ref) { 
    //do something 
    std::cout<<"const Sptr\n"; 
    ref->AddRef(); 
} 

template <typename T> 
Sptr<T>::~Sptr() { 
    //do something 
    if(ref->Release() == 0) { 
     if(obj) 
      delete obj; 

     delete ref; 
    } 
} 

template <typename T> 
template <typename U> 
Sptr<T>::Sptr(U* u) : obj(u),ref(NULL) { 
    //do something 
    ref = new RC(); 
    ref->AddRef(); 
} 

template <typename T> 
template <typename U> 
Sptr<T>::Sptr(const Sptr<U> &u) : obj(u.obj),ref(u.ref) { 
    std::cout<<"const Sptr<U>\n"; 
    ref->AddRef(); 
} 

EDIT

的析構函數不是虛擬的。這是我必須解決的問題。下面是Base1Derived

class Base1 { 
    protected: 
     Base1() : derived_destructor_called(false) { 
      printf("Base1::Base1()\n"); 
     } 
    private: 
     Base1(const Base1 &); // Disallow. 
     Base1 &operator=(const Base1 &); // Disallow. 
    protected: 
     ~Base1() { 
      printf("Base1::~Base1()\n"); 
      assert(derived_destructor_called); 
     } 
    protected: 
     bool derived_destructor_called; 
}; 

class Derived : public Base1 { 
     friend void basic_tests_1(); 
    private: 
     Derived() {} 
     Derived(const Derived &); // Disallow. 
     Derived &operator=(const Derived &); // Disallow. 
    public: 
     ~Derived() { 
      printf("Derived::~Derived()\n"); 
      derived_destructor_called = true; 
     } 
     int value; 
}; 
+0

它應該甚至很重要,如果你的析構函數是虛擬的? – dtech 2013-04-08 20:16:24

+0

析構函數不是虛擬 – footy 2013-04-08 20:19:53

+0

你應該閱讀關於'std :: unique_ptr'如何使用deleter解決這個問題:http://stackoverflow.com/q/8274451/103167 – 2013-04-08 20:27:39

回答

2

如果你把你的構造函數模板,你可以檢測指針在構造時傳入的類型和保存到您的智能指針(例如,在多態缺失者目的)。這是(我相信)shared_ptr<>是如何做到的。如果傳入的指針類型沒有可訪問的析構函數,那麼也可以使用SFINAE來產生編譯器錯誤。

相關問題