在介紹scoped_ptr之前,我們先回顧一下前兩篇文章的內容.
首先,智能指針采用RAII機制,通過對象來管理指針,構造對象時,完成資源的初始化;析構對象時,對資源進行清理及汕尾.
auto_ptr,通過轉移管理權來完成對象的拷貝與賦值,在實際開發中並不實用.
回顧完智能指針的背景及auto_ptr的特性之后,本文來介紹scoped_ptr的實現原理及特性.
scoped_ptr與auto_ptr類似,但最大的區別就是它不能轉讓管理權.也就是說,scoped_ptr禁止用戶進行拷貝與賦值.
誒?當我了解到這里的時候,那么問題來了:scoped_ptr是通過什么方法來做到禁止用戶進行拷貝與賦值呢?
換句話說:C++中有什么方法可以禁止一個類進行拷貝構造和賦值呢?
那么我第一時間想到的是:既然禁止你進行拷貝和賦值,那我不寫相應函數不就行了?
在C++中,如果你不定義拷貝構造函數/賦值運算符重載函數的話,當你在調用時,系統會自動默認生成相應的函數.
但,系統默認生成的函數,完成的僅僅是值的拷貝,即淺拷貝!(當然,深淺拷貝的問題,就不在這里多說了,以后再談.)
也就是說,這種方法絕對沒辦法禁止一個類進行拷貝構造與賦值.
此時,我突然靈光一現:想起了《Effective C++》中某條款提到了這個,其實要做的很簡單:
我們只需把拷貝構造函數與賦值運算符重載的訪問限定符設置為private,並且只給出其聲明,就像這樣:
class ScopedPtr{ private: ScopedPtr(const ScopedPtr& sp); ScopedPtr& operator(const ScopedPtr& sp); };
因此,scoped_ptr的"核心技術",再次被我們所剖析、掌握!
最終,給出我寫的精簡版代碼:
/* *文件說明:模擬實現scoped_ptr *作者:高小調 *日期:2017-03-31 *集成開發環境:Microsoft Visual Studio 2010 */ #pragma once template<typename T> class ScopedPtr{ public: //構造函數 ScopedPtr(T* ptr = NULL) :_ptr(ptr){} //析構函數 ~ScopedPtr(){ if(_ptr!=NULL){ delete _ptr; _ptr=NULL; } } private: //拷貝構造 ScopedPtr(const ScopedPtr &sp); //賦值運算符重載 ScopedPtr& operator=(const ScopedPtr &sp); private: T *_ptr; }; void TestScopedPtr(){ ScopedPtr<int> sp1(new int(10)); ScopedPtr<int> sp2(new int(20)); //ScopedPtr<int> sp3(sp1); //錯誤 //sp1 = sp2 //錯誤 }