2013-03-31 91 views
0

我正在實現一個名爲Sprt的類(基本上是一個智能指針作爲練習),下面是聲明。爲了清楚起見,我省略了實施。還有2個類來測試它。我已經包括他們的代碼。但是當我在函數basic_tests_1中編寫測試代碼時,出現編譯器錯誤。我不清楚如何解決它。有什麼問題?糾正模板類問題

#include <iostream> 
#include <stdio.h> 
#include <assert.h> 

namespace my { 
    template <class T> 
    class Sptr { 
    private: 
     //some kind of pointer 
      //one to current obj 
     T obj; 
     size_t reference_count; 
      //one to original obj 
    public: 
     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> &); 

     void reset(); 

     T* operator->() const 
     {return &obj;}; 

     T& operator*() const 
     {return obj;}; 

     T* get() const 
     {return &obj;}; 

    }; 
} 


using namespace std; 
using namespace my; 
/* Basic Tests 1 ================================================================================ */ 

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


void basic_tests_1() { 


    // Test deleting through original class. 
    { 
     // Base1 created directly with Derived *. 
     { 
      Sptr<Base1> sp(new Derived); 
      { 
       // Test copy constructor. 
       Sptr<Base1> sp2(sp); 
      } 
     } 
     // Base1 assigned from Sptr<Derived>. 
     { 
      Sptr<Base1> sp2; 
      { 
       Sptr<Derived> sp(new Derived); 
       // Test template copy constructor. 
       Sptr<Base1> sp3(sp); 
       sp2 = sp; 
       sp2 = sp2; 
      } 
     } 
    } 
} 

int main(int argc, char *argv[]) { 

    cout << "Hello world"; 
    basic_tests_1(); 

    return 0; 
} 

以下是編譯器錯誤:

Sptr.cpp: In destructor ‘my::Sptr<Base1>::~Sptr()’: 
Sptr.cpp:109:9: error: ‘Base1::~Base1()’ is protected 
Sptr.cpp:8:8: error: within this context 
Sptr.cpp: In function ‘void basic_tests_1()’: 
Sptr.cpp:142:39: note: synthesized method ‘my::Sptr<Base1>::~Sptr()’ first required here 
Sptr.cpp: In member function ‘my::Sptr<Base1>& my::Sptr<Base1>::operator=(const my::Sptr<Base1>&)’: 
Sptr.cpp:107:16: error: ‘Base1& Base1::operator=(const Base1&)’ is private 
Sptr.cpp:8:8: error: within this context 
Sptr.cpp: In function ‘void basic_tests_1()’: 
Sptr.cpp:156:23: note: synthesized method ‘my::Sptr<Base1>& my::Sptr<Base1>::operator=(const my::Sptr<Base1>&)’ first required here 
Sptr.cpp: In instantiation of ‘my::Sptr<T>::Sptr(U*) [with U = Derived; T = Base1]’: 
Sptr.cpp:142:39: required from here 
Sptr.cpp:102:9: error: ‘Base1::Base1()’ is protected 
Sptr.cpp:56:20: error: within this context 
Sptr.cpp:109:9: error: ‘Base1::~Base1()’ is protected 
Sptr.cpp:56:20: error: within this context 
Sptr.cpp: In instantiation of ‘my::Sptr<T>::Sptr(const my::Sptr<T>&) [with T = Base1]’: 
Sptr.cpp:145:35: required from here 
Sptr.cpp:102:9: error: ‘Base1::Base1()’ is protected 
Sptr.cpp:61:38: error: within this context 
Sptr.cpp:109:9: error: ‘Base1::~Base1()’ is protected 
Sptr.cpp:61:38: error: within this context 
Sptr.cpp: In instantiation of ‘my::Sptr<T>::Sptr() [with T = Base1]’: 
Sptr.cpp:150:25: required from here 
Sptr.cpp:102:9: error: ‘Base1::Base1()’ is protected 
Sptr.cpp:50:16: error: within this context 
Sptr.cpp:109:9: error: ‘Base1::~Base1()’ is protected 
Sptr.cpp:50:16: error: within this context 
Sptr.cpp: In instantiation of ‘my::Sptr<T>::Sptr(U*) [with U = Derived; T = Derived]’: 
Sptr.cpp:152:45: required from here 
Sptr.cpp:120:9: error: ‘Derived::Derived()’ is private 
Sptr.cpp:56:20: error: within this context 

回答

1

看起來你BASE1析構函數應予以公開。你也應該聲明它是虛擬的,否則派生類析構函數將不會被正確調用。此外,您正在base1中定義operator =,並將其派生爲private,然後在將測試代碼中的另一個共享ptr實例分配給另一個實例時嘗試使用它們。其餘的錯誤與被保護的base1構造函數有關,這意味着你不能直接實例化它。如果你真的想創建base1對象,你可以使構造函數公開。

+0

它仍然有錯誤「Base1&Base1 :: operator =(const Base1&)'private'to below。如果我公開所有的方法,這個錯誤仍然存​​在。 – footy

+1

+1使析構函數變爲虛擬。另外,爲什麼一個智能指針類不是完全存儲一個指針而是一個值。這不是T * obj嗎?除此之外,JS的建議應該/將會工作。如果它沒有使用新代碼進行更新,並且在進行這些更改後出現新錯誤。 – user2184879