2016-12-29 27 views
1

我想在C++中使用模板來實現智能指針(基本上是唯一的指針),以便於理解。在C++中使用模板的SmartPointer

這是我已經編寫

using namespace std; 

template<typename T> 
class smartPointer 
{ 
    private: 
     T *mPtr; 
    public: 
     smartPointer(T* init=nullptr):mPtr(init) 
     { 
      cout<<"Inside ctr"<<endl; 
     } 


     //silence the default ctr 
     smartPointer() = delete; 

     //disable copy ctr and copy assignment 
     smartPointer (const smartPointer& other) = delete; 
     smartPointer& operator=(const smartPointer& other) = delete; 

     //implement move ctr and move assignment 
     smartPointer (smartPointer&& other) 
     { 
      cout<<"Inside move ctr "<<endl; 
      mPtr = other.mPtr; 
      other.mPtr = nullptr; 
     } 
     smartPointer& operator=(smartPointer&& other) 
     { 

      cout<<"Inside move = before "<<endl; 
      if(&other != this) 
      { 
       mPtr = other.mPtr; 
       other.mPtr = nullptr; 

       cout<<"Inside move = after "<<endl; 
      } 
     return *this; 
     } 

     //deference 
     T& operator*() 
     { 
      return *mPtr; 
     } 

     //arrow access operator 
     T* operator->() 
     { 
      return mPtr; 
     } 

     ~smartPointer() 
     { 
      cout<<"Inside ~dtr"<<endl; 
      if(mPtr != nullptr) 
      delete mPtr; 
     } 

}; 



int main() 
{ 

    smartPointer<int> sptr(new int); 

    // Even smartPointer<int> sptr(new int[20]); too works 

    *sptr = 10; 
    cout<<"Value pointed by the pointer is "<<*sptr<<endl;  

    smartPointer<int> sptr2(new int); 

// sptr2 = sptr; // complains as expected 
    sptr2 = move(sptr); // works well 

    /* 
    How to 

    smartPointer<int[]> sptr(new int[20]); 
    */ 

    return 0; 
} 

如何讓這個智能指針爲智能指針工作?

構建指令I得到是 克++ -std = C++ 11 -smartPointer.cpp -o智能指針

+0

請[刪除'使用命名空間std;'](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)。 – Quentin

回答

1

可以添加operator[]到基本模板,並使用SFINAE,以確保它僅當編譯的類型是一個數組類型。您也可以這樣做,以確保operaotr*operaotr->僅針對非陣列版本進行編譯。然後,可以使用標籤調度來調用正確的delete表達式。

template<typename T> 
class smartPointer 
{ 
    private: 
     T *mPtr; 

     del_member(std::true_type) { delete[] mPtr; } 
     del_member(std::false_type) { delete mPtr; } 

    public: 
     // Removed you code for brevity. 

     //deference 
     auto operator*() -> std::enable_if_t<!std::is_array<T>::value, T&> 
     { 
      return *mPtr; 
     } 

     //arrow access operator 
     auto operator->() -> std::enable_if_t<!std::is_array<T>::value, T*> 
     { 
      return mPtr; 
     } 

     auto operator[](std::size_t idx) -> std::enable_if_t<std::is_array<T>::value, T&> 
     { 
      return mPtr[idx]; 
     } 

     ~smartPointer() 
     { 
      del_member(std::is_array<T>{}); 
     } 
}; 

以上是完全合法的,可以存在於同一模板中。記住模板的成員僅在使用時才被實例化。因此,除非你的類的用戶嘗試使用底層指針不應該支持的操作符,否則它們將不會出現錯誤。


如果你的編譯器不支持C++ 14型特質的是,上述尾隨返回類型可以轉向形式:

typename std::enable_if<CONDITION, TYPE>::type 

爲了您c'tor,我建議你不要硬編碼T*。相反,請將以下類型別名添加到您的課程中,並相應地更改c'tor。

using ptr_type = std::conditional_t<std::is_array<T>::value, std::decayt_t<T>, std::add_pointer_t<T>>; 

smartPointer(ptr_type init) 
+1

非常感謝。我接受你的答案。謝謝:)學了一個新東西SIFNAE,並感謝您非常快速的回覆:) – balu

+0

你能幫我在構造函數中,我得到這個錯誤 錯誤:沒有匹配函數調用'smartPointer :: smartPointer(int * )' smartPointer sptr(new int [20]); – balu

+0

@balu - 查看我的編輯。 Buf如果你有更多的問題,請發表另一個問題。 SO不是論壇。 – StoryTeller