'全面剖析 C++ Boost 智能指針!| CSDN 博文精選'

CSDN Java 設計 算法 CSDN 2019-09-04
""全面剖析 C++ Boost 智能指針!| CSDN 博文精選"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

shared_ptr 同 weak_ptr的比較:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

shared_ptr 同 weak_ptr的比較:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

shared_ptr 同 weak_ptr的比較:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

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提供了計數器功能:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

shared_ptr 同 weak_ptr的比較:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

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提供了計數器功能:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

在主函數中測試一下:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

shared_ptr 同 weak_ptr的比較:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

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提供了計數器功能:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

在主函數中測試一下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

shared_ptr 同 weak_ptr的比較:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

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提供了計數器功能:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

在主函數中測試一下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

聲明:本文為CSDN博主「.NY&XX」的原創文章,版權歸作者所有,如需轉載請聯繫作者。

原文:https://blog.csdn.net/songguangfan/article/details/96361648

【END】

"全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

作者 | .NY&XX

責編 | 屠敏

出品 | CSDN 博客

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

為什麼要使用智能指針

C++沒有提供類似JAVA的垃圾回收機制,因此Boost可以通過智能指針來管理內存避免一些問題。C++繼承C高效靈活地指針,但是同樣帶了了很多問題:

  1. 內存洩露

  2. 野指針

  3. 越界訪問

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

什麼是智能指針

智能指針是一種像指針的C++對象,但它能夠在對象不使用的時候自己銷燬掉。雖然STL提供了auto_ptr,但是由於不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應用最為廣泛的一個。使用智能指針需包含以下頭文件,如果只使用智能指針 shared_ptr 可以只包含同名頭文件。

#include <boost/smart_ptr.hpp>

using namespace boost;

Boost主要包含以下幾種智能指針:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_ptr

主要特點

  1. scoped_ptr 是Boost 提供的一個簡單的智能指針只限於作用域內使用

  2. 指針管理權不可轉移,不支持拷貝構造函數與賦值操作。

這種智能指針只限於作用域內使用,無法轉移內置指針的管理權(不支持拷貝、=賦值等) 但是作用也很顯然。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

假設定義到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也禁止拷貝、賦值。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::scope_array

主要特點

同 boost::scoped_ptr 基本一樣,只是接受數組的new ,多了下標訪問操作,其他類似。

  1. 構造函數指針必須是 new 的結果,而不能是 new 表達式的結果

  2. 沒有 *, -> 操作符重載,因為 scoped_array 持有的不是一個普通指針

  3. 析構函數使用 delete 釋放資源,而不是 delete

  4. 提供 operator 操作符重載,可以像普通數組一樣用下標訪問

  5. 沒有 begin, end 等類似容器迭代器操作函數

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

具體用法

scoped_array 輕巧方便,沒有給程序增加額外負擔,但是 scoped_array 功能有限,不能動態增長,也沒有迭代器支持,不能搭配 STL 算法,僅有一個純粹的“裸”數組接口。在需要動態數組的情況下我們應該使用 std::vector 。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::shared_ptr

主要特點

boost.smart_ptr 庫中最有價值,最重要的組成部分。支持拷貝構造函數、支持賦值操作。重載了*和->操作符用來模仿原始指針的行為。目前已成為tr1標準的一部分,發展自原始的auto_ptr,內置引用計數。引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷燬的時候,那麼就銷燬對象本身。

  1. 支持拷貝構造函數,賦值操作。

  2. 重載 * 和 -> 操作符模仿原始指針。

  3. 內置引用計數。

但是,使用的時候需要注意以下幾點:

  1. 同scope_ptr一樣,禁止get得到指針地址後,執行delete。

  2. 禁止循環引用,否則會出內存洩漏。

  3. 不能作為函數的臨時參數。

  4. shared_ptr是線程安全的。

  5. shared_ptr支持強制類型轉換,如果定義了一個U能夠強制轉換到T(因為T是U的基類),那麼shared_ptr也能夠強制轉換到shared_ptr。

具體用法

具體使用例子如下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

當遇到深拷貝問題時,如果成員變量是shared_ptr類型可以考慮不用自己編寫拷貝和賦值構造函數。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

實際上,智能指針賦值拷貝的同時,引用計數也加1了。在默認析構函數也是如此,析構函數執行之後,會調用類A的析構函數,檢查引用計數都為0後,會delete掉這個int。從而完美的完成了無內存洩漏的、無內存出錯的、多個實例之間的指針變量共享。

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

boost::weak_ptr

主要特點

weak_ptr 被設計為與 shared_ptr 共同工作,可以從一個 shared_ptr 或者另一個 weak_ptr 對象構造,獲得資源的觀測權。但是 weak_ptr 沒有共享資源,它的構造不會引起指針引用計數的增加,同時,在析構的時候也不回引起引用計數的減少。

具體用法

shared_ptr有個致命缺陷,循環引用不能夠自動回收。看如下的例子:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

由於A和B相互引用,它們的計數永遠都為2,所以這樣使用shared_ptr必然會導致內存洩漏。為了解決這個問題,可以採用boost::weak_ptr來隔斷交叉引用中的迴路;boost::weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。弱引用不更改引用計數,類似普通指針,只要把循環引用的一方使用弱引用,即可解除循環引用。例如:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

shared_ptr 同 weak_ptr的比較:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選全面剖析 C++ Boost 智能指針!| CSDN 博文精選

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提供了計數器功能:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

在主函數中測試一下:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

運行結果:

全面剖析 C++ Boost 智能指針!| CSDN 博文精選

聲明:本文為CSDN博主「.NY&XX」的原創文章,版權歸作者所有,如需轉載請聯繫作者。

原文:https://blog.csdn.net/songguangfan/article/details/96361648

【END】

全面剖析 C++ Boost 智能指針!| CSDN 博文精選"

相關推薦

推薦中...