C++智能指针模板类
對于常規類指針,可能由于忘記釋放內存而導致內存泄漏,有三種智能指針可以解決這類問題。
對于常規指針,它沒有析構函數,加入指針成為了對象,那么,在對象過期時就會自動調用析構函數,讓析構函數釋放指針指向的內存。C++98提供了auto_ptr,C++11將其摒棄,提供了unique_ptr和shared_ptr。
智能指針的使用
三個智能指針模板都定義了類似指針的對象,可以將new獲得的地址賦值給這種對象,當智能指針過期時,將自動調用析構函數,讓析構函數調用delete用來釋放內存。
如果要創建智能指針對象,必須包含頭文件memory,然后使用通常的模板實例化所需指針類型
auto_ptr<double>ps(new double);如同這個例子,使用new來分配一個double類型的地址,返回其地址,然后初始化給使用auto_ptr創建的指向double類型的指針,其他兩種類型的指針用法也是這樣。
需要注意,智能指針模板位于名稱空間std中
所有智能指針類都有一個explcit構造函數,因此隱式類型轉換是不允許的。
智能指針模板類的定義很多方面都類似于常規指針,可以對它進行解引操作,用間接成員運算符訪問結構成員,將其賦值給常規指針,將其賦值給同類型智能指針對象。
不能把delete應用于非堆內存,因此下面的用法是錯誤的:
int a=5; unique_ptr<int>(&a);注意
假如進行某些操作,兩個智能指針指向了同一個對象,加入指針是常規指針,那么釋放內存時就對同一位置的內存釋放了兩次,為解決這種問題,智能指針采用了不同的方法:
- 定義賦值運算符,進行深賦值,令一個指針指向另一個指針指向對象的副本。這是一種可行的解決方法,但是這三種智能指針采用了別的方法。
- 建立所有權概念: 對于特定的對象,只能有一個智能指針可以擁有它,賦值操作后所有權轉讓,原來的指針變為空的,這是unique_ptr和auto_ptr采用的策略,其中前者更為要求更為嚴格。
- 引用計數: 跟蹤引用特定對象的智能指針數,賦值時令引用計數加一,過期時減一,當最后一個指針過期時才調用delete來釋放內存,這是shared_ptr采用的策略。
unique_ptr和auto_ptr的比較
auto_ptr<int>p1(new int(666)); auto_ptr<int>p2; p2=p1;對于使用auto_ptr來講,當所有權轉讓后,原來的指針不再指向所有對象,但是當再企圖使用這個指針時,這就是一件不愿意發生的事。
然而對于unique_ptr來講,它會直接定義上面的賦值是錯誤的,因為它留下了一個懸掛的指針(指向無效數據的指針)。
不過,有時候,智能指針賦值并不會留下懸掛的指針:
unique_ptr<int> f1(const int a) {unique_ptr<int>temp(new int(a));return temp; } unique_ptr<int>ps(f1(666));這樣的話,f1()返回一個臨時的智能指針,在將其賦值給ps后,這個臨時指針就會被銷毀,并沒有留下懸掛的指針,因此,編譯器是允許這種賦值的。
因此,當將unique_ptr指針賦值給另一個時,如果是一個臨時的右值,那么編譯器允許這樣做,但是如果源指針存留一段時間,將會報錯。
還有一點需要注意 使用new 分配內存時,才可以使用auto_ptr和shared_ptr ;使用new和new[]分配內存時才可以使用unique_ptr
另外,如果編譯器未提供shared_ptr,可以使用Boost庫的shared_ptr指針,另外,此庫還提供了scoped_ptr指針,與unique_ptr類似,用作編譯器未提供unique_ptr時的替代。
?
總結
以上是生活随笔為你收集整理的C++智能指针模板类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FastAPI框架诞生的缘由(上)
- 下一篇: 死锁的概念以及发生死锁的缘由