天天看點

c++11學習筆記(6)- 智能指針1. unique_ptr2. shared_ptr3. weak_ptr

文章目錄

  • 1. unique_ptr
  • 2. shared_ptr
  • 3. weak_ptr

智能指針在C++11以前就已經存在了,使用的是 auto_ptr 作為隻能指針,不過 auto_ptr 有一個缺點,拷貝時傳回一個左值,不能調用delete[]等,是以在C++11中被棄用了。C++11中使用 unique_ptr 、shared_ptr 、weak_ptr 等智能指針回收堆配置設定的對象。

1. unique_ptr

  • 與所指對象的記憶體緊密綁定,不與其他 unique_ptr 類型的指針對象共享所指對象的記憶體。
  • 從實作上講, unique_ptr 則是一個删除了拷貝構造函數、保留了移動構造函數的指針封裝類型。程式員僅可以使用右值對 unique_ptr 對象進行構造,而且一旦構造成功,右值對象中的指針就會被“竊取”,是以該右值對象即刻失去對指針的所有權。

我們來看下面的一個例子:

#include <iostream>
#include <memory>
#include <stdlib.h>

int main(int argc, char** argv)
{
	std::unique_ptr<int> pUniquePtr(new int(10));

	std::cout << *pUniquePtr << std::endl;

	std::unique_ptr<int> pUniquePtr2 = std::move(pUniquePtr);
	std::cout << *pUniquePtr2 << std::endl;

	// std::cout << *pUniquePtr << std::endl; (此句運作崩潰)

	system("pause");
	return 0;
}

           

程式的運作結果為

10

10

如果在程式的第14行的注釋去掉,則運作崩潰,因為指針對象已經被 pUniquePtr2 竊取了。

2. shared_ptr

與 unique_ptr 不同, shared_ptr 實際上采用的引用計數,是以一旦一個 shared_ptr 指針放棄了所有權,其他的 shared_ptr 對象不會受到影響,當引用計數為0的時候才釋放指向的堆記憶體。

下面時一個簡單的示例:

#include <iostream>
#include <memory>
#include <stdlib.h>

int main(int argc, char** argv)
{
	std::shared_ptr<int> pSharedPtr1(new int(10));

	std::cout << *pSharedPtr1 << std::endl;

	std::shared_ptr<int> pSharedPtr2 = pSharedPtr1;
	std::cout << *pSharedPtr2 << std::endl;

	std::cout << *pSharedPtr2 << std::endl;

	system("pause");
	return 0;
}

           

程式的運作結果為:

10

10

10

3. weak_ptr

weak_ptr 可以指向 shared_ptr 指針指向的對象記憶體,卻不擁有該記憶體。而使用 weak_ptr 成員 lock ,則可傳回指向記憶體的一個 shared_ptr 對象,且所指向的記憶體無效時,傳回空指針(nullptr)。

下面是一個簡單的示例:

#include <iostream>
#include <memory>
#include <stdlib.h>

int main(int argc, char** argv)
{
	std::shared_ptr<int> pSharedPtr1(new int(10));
	std::shared_ptr<int> pSharedPtr2 = pSharedPtr1;
	std::weak_ptr<int> pWeakPtr = pSharedPtr2;

	std::shared_ptr<int> sp = pWeakPtr.lock();
	if (sp != nullptr)
		std::cout << *sp << std::endl;

	sp.reset();
	pSharedPtr1.reset();
	pSharedPtr2.reset();

	std::shared_ptr<int> sp2 = pWeakPtr.lock();
	if (sp2 != nullptr)
		std::cout << *sp2 << std::endl;

	system("pause");
	return 0;
}

           

結果為:

10

當調用

sp.reset();
pSharedPtr1.reset();
pSharedPtr2.reset();
           

時,其引用計數為0,資源被釋放,是以在調用 **std::shared_ptr sp2 = pWeakPtr.lock();**時,傳回的對象為 nullptr

作者:douzhq

個人首頁:https://www.douzhq.cn

文章同步頁:https://douzhq.cn/c11_6/

繼續閱讀