使用普通指標,容易造成堆記憶體洩露(忘記釋放),二次釋放,程式發生異常時記憶體洩露等問題等,使用智慧型指標能更好的管理堆記憶體。
stl一共給我們提供了四種智慧型指標:auto_ptr、unique_ptr、shared_ptr和weak_ptr。
auto_ptr是c++98提供的解決方案,c+11已將將其摒棄。
template class smart_ptr
smart_ptr& operator=(smart_ptr& rhs)
…t* release()
void swap(smart_ptr& rhs)
…};
在拷貝建構函式中,通過呼叫 other 的 release 方法來釋放它對指標的所有權。在賦值函式中,則通過拷貝構造產生乙個臨時物件並呼叫 swap 來交換對指標的所有權。
使用了copy and swap策略,保證了強異常安全性。即使發生異常的話,this 物件完全不受任何影響。
帶來的問題:
auto_ptr< string> sm_ptr1 (new string ("i am sm_ptr1.」);
auto_ptrsm_ptr2;
sm_ptr1 = sm_ptr2;
兩個auto_ptr指標將指向同乙個string物件,可能造成刪除同乙個物件兩次。
shared_ptr採用引用計數(賦值時,計數將加1,而指標過期時,計數將減1)。當減為0時才呼叫delete。不會有上述問題。
class shared_count
void add_count()
long reduce_count()
long get_count() const
private:
long count_;
};template class smart_ptr
} ~smart_ptr()
}private:
t* ptr_;
shared_count* shared_count_;
};
unique_ptr優於auto_ptr的地方:
當程式試圖將乙個 unique_ptr 賦值給另乙個時,如果源 unique_ptr 是個臨時右值,編譯器允許這麼做;如果源 unique_ptr 將存在一段時間,編譯器將禁止這麼做。
忘記delete,造成記憶體洩漏
unique_ptr 乙個最簡單的使用場景是用於類。
按照 unique_ptr 的寫法,不用在析構函式手動 delete ,當物件析構時,將會自動釋放記憶體。
異常安全
void process()
在正常流程下,我們會在函式末尾 delete 建立的物件 w,正常呼叫析構函式,釋放記憶體。
但是如果w->do_something()
發生了異常,那麼delete w
將不會被執行。此時就會發生 記憶體洩漏。
如果我們用 std::unique_ptr,那麼這個問題就迎刃而解了。無論**怎麼拋異常,在 unique_ptr 離開函式作用域的時候,記憶體就將會自動釋放。
要把指標存入標準庫容器
不管容器中儲存的是普通指標還是智慧型指標,在使用上,兩者並無太大區別,使用智慧型指標的優越性主要體現在容器使用完畢後清空容器的操作上。如果容器中儲存的是普通指標,當我們在清空某個容器時,先要釋放容器中指標所指向的資源,然後才能清空這些指標本身。
shared_ptr:
有多個使用者共同使用同乙個物件,而這個物件沒有乙個明確的擁有者;
某乙個物件的複製操作很費時;
如果乙個物件的複製操作很費時,同時我們又需要在函式間傳遞這個物件,我們往往會選擇傳遞指向這個物件的指標來代替傳遞物件本身,以此來避免物件的複製操作。既然選擇使用指標,那麼使用shared_ptr是乙個更好的選擇,即起到了向函式傳遞物件的作用,又不用為釋放物件操心。
我們往往會需要在類內部使用自身的 shared_ptr,例如:
class widget
}
我們需要把當前 shared_ptr 物件同時交由物件 a 進行管理。意味著,當前物件的生命週期的結束不能早於物件 a。因為物件 a 在析構之前還是有可能會使用到a.widget
。
如果我們直接a.widget = this;
, 那肯定不行, 因為這樣並沒有增加當前 shared_ptr 的引用計數。shared_ptr 還是有可能早於物件 a 釋放。
如果我們使用a.widget = std::make_shared(this);
,肯定也不行,因為這個新建立的 shared_ptr,跟當前物件的 shared_ptr 毫無關係。當前物件的 shared_ptr 生命週期結束後,依然會釋放掉當前記憶體,那麼之後 a.widget 依然是不合法的。
對於這種,需要在物件內部獲取該物件自身的 shared_ptr, 那麼該類必須繼承std::enable_shared_from_this
。**如下:
class widget : public std::enable_shared_from_this
}
c 智慧型指標
auto prt 它是 它所指向物件的擁有者 所以當自身物件被摧毀時候,該物件也將遭受摧毀,要求乙個物件只有乙個擁有者,注意 auto prt 不能使用new 來分配物件給他 include include using namespace std template void bad print au...
c 智慧型指標
很久沒寫部落格了,不知道如何表達了,哈哈.我先介紹一下深淺拷貝.class copy 此時a.ptr和b.ptr指向同乙個物件,當我們delete a.ptr時 b.ptr所指向的物件已經不存在了,要是我們引用b.ptr指向的物件也就會出問題了.深拷貝 把a.ptr所指向的物件拷貝乙份給b.ptr ...
c 智慧型指標
記得前不久有一次面試被問到智慧型指標的實現,當時對智慧型指標只是聽說但沒有了解過,就亂七八糟地說了一遍。今天寫了一遍智慧型指標,用了引用計數的概念。主要思想就是,用乙個新類對原本需要的型別進行了一層封裝,這個新類中儲存了原本的物件指標和乙個引用計數的指標,之所以全部用指標來儲存,就是因為會出現多個新...