C++智能指针,RAII(资源获取即初始化) 原则

转载:C++ RAII机制详解

转载:C++share_ptr智能指针的使用

中文标准库:RAII

一、unique_ptr

中文标准库:unique_ptr

尽量使用unique_ptr替代裸指针

一个unique_ptr独享它指向的对象,不能直接(使用reset才可以)将一个unique_ptr赋值给其他变量,不过shared_ptr可以。也就是说,同时只有一个unique_ptr指向同一个对象,当这个unique_ptr被销毁时,指向的对象也随即被销毁。如果一个类中包含unique_ptr,那么该类也不能使用拷贝和赋值。

数组版本

std::unique_ptr<int[]> ptr = std::make_unique<int[]>(5); //相当于 int ptr[5] = {0};

局部智能指针不能作为函数返回值,因为智能指针的作用域有限

指针

1. 获取裸指针 get()

返回指向被管理对象的指针

2. 替换被管理对象 reset()

注意:因为一个unique_ptr独享它指向的对象,因此替换被管理的对象时必须释放之前对象的所有权

std::unique_ptr<int> p1 = std::make_unique<int>(2);
std::unique_ptr<int> p2 = std::make_unique<int>(3);
p1 = p2;//错误
p1.reset(p2); //错误
p1.reset(p2.release()); //正确,此时p1管理的是大小为3的int数组对象

3. 释放被管理对象 release()

unique_ptr被销毁时(如离开作用域),对象也就自动释放了,也可以通过其他方式下显式释放对象。如:

up = nullptr; //置为空,释放up指向的对象
up.release(); //放弃控制权,返回裸指针,并将up置为空
up.reset();   //释放up指向的对象

二、share_ptr

尽量少用share_ptr

shared_ptr是支持共享所有权的引用计数型指针,“共享”指的是允许多个指针指向同一个资源,shared_ptr对象可以被拷贝与赋值,“引用计数”指的是它可以记录当前指向同一资源的指针的数量, 当计数为0的时候才会释放动态分配的对象。对shared_ptr循环引用会导致因为无法释放资源引发的内存泄漏。典型的如双链表。不要把一个裸指针给多个shared_ptr对象管理

三、weak_ptr

weak_ptr就是为了辅助shared_ptr的,它本身不能直接指向原生指针对象,只能指向shared_ptr对象。

weak_ptr总结

  • weak_ptr虽然是一个模板类,但是不能用来直接定义指向原始指针的对象。

  • weak_ptr接受shared_ptr类型的变量赋值,但是反过来是行不通的,需要使用lock函数。

  • weak_ptr设计之初就是为了服务于shared_ptr的,所以不增加引用计数就是它的核心功能。

  • 由于不知道干了什么之后weak_ptr所指向的对象就会被析构掉,所以使用之前请先使用expired函数检测一下。

转载:智能指针(3):weak_ptr浅析

四、auto_ptr

被摒弃 https://www.cnblogs.com/lanxuezaipiao/p/4132096.html

示例代码

点击查看代码
#include <iostream>
#include <memory>

class A
{
public:
	std::shared_ptr<int> sharedInt = std::make_shared<int>(1);
	//std::unique_ptr<int> uniqueInt = std::make_unique<int>(2);
	void show() { std::cout << *sharedInt << "
"; }
};

int main()
{
	A a;
	a.show();
	A a1 = a;  //如果类A中有unique_ptr报错
	A a2 = a1;

	std::cout << a.sharedInt.use_count();  //3

	///< Shared_ptr
	auto s1 = std::make_shared<int>(1);
	auto s2 = std::make_shared<int>(2);
	auto s3 = std::make_shared<int>(3);

	std::shared_ptr<int> ps1;
	std::shared_ptr<int> ps2;
	auto c1 = s1.use_count(); //1
	auto c2 = s2.use_count(); //1
	auto c3 = s3.use_count(); //1
	auto c4 = ps1.use_count(); //0
	auto c5 = ps2.use_count(); //0

	ps1 = s1;  //共享s1指向的对象(unique_ptr不支持)
	auto c6 = ps1.use_count(); //2
	auto c7 = s1.use_count(); //2
	ps2 = s1;
	auto c8 = s1.use_count(); //3
	auto c9 = ps2.use_count(); //3


	///< unique_ptr
	std::unique_ptr<int> pu1 = std::make_unique<int>(2);
	std::unique_ptr<int> pu2 = std::make_unique<int>(3);
	//p1.reset(p2); //错误
	//std::unique_ptr<int> pu6 = pu1; //错误,因为unique_ptr独享它指向的对象(可以用shared_ptr共享)
	pu1.reset(pu2.release()); //正确,此时p1管理的是值为3的int指针

	auto pu1Value1 = *pu1.get();

	std::unique_ptr<int[]> pu3 = std::make_unique<int[]>(9);  //大小为9的int数组
	std::unique_ptr<int[]> pu4 = std::unique_ptr<int[]>(new int[3]); //大小为3的int数组,不推荐使用new

	std::unique_ptr<int[]> pu5;

	int arr[5] = { 0 };
	int* pu6 = new int[8];
	pu4.reset(arr);
	pu5.reset(pu6);

	//std::unique_ptr<int[]> pu7(pu3);  //错误
	std::unique_ptr<int[]> pu7(std::move(pu3));//正确

	//pu5.reset(std::move(pu3));  //错误
	//pu4.reset(pu3); //错误
	pu5.reset(pu3.release()); //正确
	
	(*pu1) = 99;  //给pu1赋值
	auto pu1Value2 = *pu1;


	system("pause");
	return 0;
}
原文地址:https://www.cnblogs.com/mmmmmmmmm/p/14512823.html