作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
運行結果:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
運行結果:
shared_ptr 同 weak_ptr的比較:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
運行結果:
shared_ptr 同 weak_ptr的比較:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
運行結果:
shared_ptr 同 weak_ptr的比較:
intrusive_ptr
主要特點
雖然boost::shared_ptr 比普通指針提供了更完善的功能。有一個小小的代價,那就是一個共享指針比普通指針佔用更多的空間,每一個對象都有一個共享指針,這個指針有引用計數器以便於釋放。boost::intrusive_ptr是一種“侵入式”的引用計數指針,是boost::shared_ptr的插入式版本。實際並不提供引用計數功能,而是要求被存儲的對象自己實現引用計數功能。可以應用於以下兩種情形:
對內存佔用要求非常嚴格,智能指針大小必須與裸指針一樣;
現存代碼已經有了引用計數機制管理的對象。而又沒有時間去維護它(或者已經不能獲取這些代碼了)。
intrusive_ptr與使用shared_ptr相比,有兩個主要的不同之處。第一個是你需要提供引用計數的機制。第二個是把this當成智能指針是合法的。
具體用法
要使用 boost::intrusive_ptr, 要包含 “boost/intrusive_ptr.hpp” 並定義兩個普通函數 intrusive_ptr_add_ref 和 intrusive_ptr_release. 它們都要接受一個參數。
一般最好泛化這兩個函數,簡單地調用被管理類型的成員函數去完成工作。
我們來看一個例子,RefCount提供了計數器功能:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
運行結果:
shared_ptr 同 weak_ptr的比較:
intrusive_ptr
主要特點
雖然boost::shared_ptr 比普通指針提供了更完善的功能。有一個小小的代價,那就是一個共享指針比普通指針佔用更多的空間,每一個對象都有一個共享指針,這個指針有引用計數器以便於釋放。boost::intrusive_ptr是一種“侵入式”的引用計數指針,是boost::shared_ptr的插入式版本。實際並不提供引用計數功能,而是要求被存儲的對象自己實現引用計數功能。可以應用於以下兩種情形:
對內存佔用要求非常嚴格,智能指針大小必須與裸指針一樣;
現存代碼已經有了引用計數機制管理的對象。而又沒有時間去維護它(或者已經不能獲取這些代碼了)。
intrusive_ptr與使用shared_ptr相比,有兩個主要的不同之處。第一個是你需要提供引用計數的機制。第二個是把this當成智能指針是合法的。
具體用法
要使用 boost::intrusive_ptr, 要包含 “boost/intrusive_ptr.hpp” 並定義兩個普通函數 intrusive_ptr_add_ref 和 intrusive_ptr_release. 它們都要接受一個參數。
一般最好泛化這兩個函數,簡單地調用被管理類型的成員函數去完成工作。
我們來看一個例子,RefCount提供了計數器功能:
在主函數中測試一下:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
運行結果:
shared_ptr 同 weak_ptr的比較:
intrusive_ptr
主要特點
雖然boost::shared_ptr 比普通指針提供了更完善的功能。有一個小小的代價,那就是一個共享指針比普通指針佔用更多的空間,每一個對象都有一個共享指針,這個指針有引用計數器以便於釋放。boost::intrusive_ptr是一種“侵入式”的引用計數指針,是boost::shared_ptr的插入式版本。實際並不提供引用計數功能,而是要求被存儲的對象自己實現引用計數功能。可以應用於以下兩種情形:
對內存佔用要求非常嚴格,智能指針大小必須與裸指針一樣;
現存代碼已經有了引用計數機制管理的對象。而又沒有時間去維護它(或者已經不能獲取這些代碼了)。
intrusive_ptr與使用shared_ptr相比,有兩個主要的不同之處。第一個是你需要提供引用計數的機制。第二個是把this當成智能指針是合法的。
具體用法
要使用 boost::intrusive_ptr, 要包含 “boost/intrusive_ptr.hpp” 並定義兩個普通函數 intrusive_ptr_add_ref 和 intrusive_ptr_release. 它們都要接受一個參數。
一般最好泛化這兩個函數,簡單地調用被管理類型的成員函數去完成工作。
我們來看一個例子,RefCount提供了計數器功能:
在主函數中測試一下:
運行結果:
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
運行結果:
shared_ptr 同 weak_ptr的比較:
intrusive_ptr
主要特點
雖然boost::shared_ptr 比普通指針提供了更完善的功能。有一個小小的代價,那就是一個共享指針比普通指針佔用更多的空間,每一個對象都有一個共享指針,這個指針有引用計數器以便於釋放。boost::intrusive_ptr是一種“侵入式”的引用計數指針,是boost::shared_ptr的插入式版本。實際並不提供引用計數功能,而是要求被存儲的對象自己實現引用計數功能。可以應用於以下兩種情形:
對內存佔用要求非常嚴格,智能指針大小必須與裸指針一樣;
現存代碼已經有了引用計數機制管理的對象。而又沒有時間去維護它(或者已經不能獲取這些代碼了)。
intrusive_ptr與使用shared_ptr相比,有兩個主要的不同之處。第一個是你需要提供引用計數的機制。第二個是把this當成智能指針是合法的。
具體用法
要使用 boost::intrusive_ptr, 要包含 “boost/intrusive_ptr.hpp” 並定義兩個普通函數 intrusive_ptr_add_ref 和 intrusive_ptr_release. 它們都要接受一個參數。
一般最好泛化這兩個函數,簡單地調用被管理類型的成員函數去完成工作。
我們來看一個例子,RefCount提供了計數器功能:
在主函數中測試一下:
運行結果:
聲明:本文為CSDN博主「.NY&XX」的原創文章,版權歸作者所有,如需轉載請聯繫作者。
原文:https://blog.csdn.net/songguangfan/article/details/96361648
【END】
"作者 | .NY&XX
責編 | 屠敏
出品 | CSDN 博客
為什麼要使用智能指針
C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:
內存洩露
野指針
越界訪問
什麼是智能指針
智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。
#include <boost/smart_ptr.hpp>
using namespace boost;
Boost主要包含以下幾種智能指針:
boost::scope_ptr
主要特點
scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用
指針管理權不可轉移,不支持拷貝構造函數與賦值操作。
這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:
假設定義到delete之中…發生了異常,那麼ptr就無法被delete,造成了內存洩漏。使用scoped_ptr就可以很好解決這個問題,只需要new的時候放到scoped_ptr之中就可以了。
具體用法
假設:
scoped_ptr ptr_t(new T); // 假設內置指針為p_t
則:
ptr_t->get,返回內部管理的指針,但禁止在get出來的指針上執行delete。
ptr_t->xxx,等同於p_t->xxx ptr_t.reset,delete內部持有的p_t。
假設T支持直接賦值,*ptr_t = xxx。
再次強調,scoped_ptr不能做拷貝、賦值等轉移指針管理權限的事情。因此,class內置域為scoped_ptr是不允許的,除非class也禁止拷貝、賦值。
boost::scope_array
主要特點
同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。
構造函數指針必須是 new 的結果,而不能是 new 表達式的結果
沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針
析構函數使用 delete 釋放資源,而不是 delete
提供 operator 操作符重載,可以像普通數組一樣用下標訪問
沒有 begin, end 等類似容器迭代器操作函數
具體用法
scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:
boost::shared_ptr
主要特點
boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。
支持拷貝構造函數,賦值操作。
重載 * 和 -> 操作符模仿原始指針。
內置引用計數。
但是,使用的時候需要注意以下幾點:
同scope_ptr一樣,禁止get得到指針地址後,執行delete。
禁止循環引用,否則會出內存洩漏。
不能作為函數的臨時參數。
shared_ptr是線程安全的。
shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。
具體用法
具體使用例子如下:
當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:
實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。
boost::weak_ptr
主要特點
weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。
具體用法
shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:
運行結果:
由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:
運行結果:
shared_ptr 同 weak_ptr的比較:
intrusive_ptr
主要特點
雖然boost::shared_ptr 比普通指針提供了更完善的功能。有一個小小的代價,那就是一個共享指針比普通指針佔用更多的空間,每一個對象都有一個共享指針,這個指針有引用計數器以便於釋放。boost::intrusive_ptr是一種“侵入式”的引用計數指針,是boost::shared_ptr的插入式版本。實際並不提供引用計數功能,而是要求被存儲的對象自己實現引用計數功能。可以應用於以下兩種情形:
對內存佔用要求非常嚴格,智能指針大小必須與裸指針一樣;
現存代碼已經有了引用計數機制管理的對象。而又沒有時間去維護它(或者已經不能獲取這些代碼了)。
intrusive_ptr與使用shared_ptr相比,有兩個主要的不同之處。第一個是你需要提供引用計數的機制。第二個是把this當成智能指針是合法的。
具體用法
要使用 boost::intrusive_ptr, 要包含 “boost/intrusive_ptr.hpp” 並定義兩個普通函數 intrusive_ptr_add_ref 和 intrusive_ptr_release. 它們都要接受一個參數。
一般最好泛化這兩個函數,簡單地調用被管理類型的成員函數去完成工作。
我們來看一個例子,RefCount提供了計數器功能:
在主函數中測試一下:
運行結果:
聲明:本文為CSDN博主「.NY&XX」的原創文章,版權歸作者所有,如需轉載請聯繫作者。
原文:https://blog.csdn.net/songguangfan/article/details/96361648
【END】
"