C++11(4内存)——智能指针

shared_ptrunique_ptr
特点使用引用计数。每个指针的拷贝都指向同一片资源独占性 不支持复制但可以转移
关于数组在C+17之前, shared_ptr能不用于管理动态分配的数组。要管理就必须自己写删除器。可以指向数组
删除器制定时,需要确认删除器的类型

本章笔记参考书《深入应用C++11》
学完以后发现书里的内容太浅了,附上我师傅 逗逼老师 的文章共参考
https://blog.csdn.net/fl2011sx/article/details/103941346

shared_ptr

分析时当模板类分析,使用时当指针使用

基本用法

初始化

// study20200206.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
#include <memory>
int main()
{
	// 1.直接初始化
	std::shared_ptr<int> p(new int(1));
	std::shared_ptr<int> p2 = p;
	std::cout << "p2.count = " << p2.use_count() <<  std::endl;

	// 2.make_shared 更高效。调用构造函数
	std::shared_ptr<int> pp = std::make_shared<int>(2);
	std::cout << "pp.count = " << pp.use_count() << std::endl;

	// 3.reset重新初始化
	std::shared_ptr<int> ptr;
	ptr.reset(new int(3));
	std::cout << "*ptr = " << *ptr;
}

获取原始指针

	std::shared_ptr<int> pp = std::make_shared<int>(2);
	int *p = pp.get();

指定删除器

初始化时也可以指定删除器(删除时候调用的函数,可以是lambda)

1. 函数作为删除器
void DeleteIntPtr(int *p) {
	delete p;
}
std::shared_ptr<int> pp(new int, DeleteIntPtr);

2. lambda
std::shared_ptr<int> pp(new int, [](int* p){ delet p; });

3. struct自定义删除器,重载()
template< typename T >
struct shared_deleter{
  void operator ()( T const * p) { 
    delete p; 
  }
};
std::shared_ptr<int> sp(new int(3), shared_deleter<int>());

shared_ptr的默认删除器不支持数组对象,可以通过以下方法指定删除器

1.std::default_delete,内部通过调用delete
std::shared_ptr<int> pp(new int[3], std::default_delete<int[]>());

2. lambda
std::shared_ptr<int> pp(new int[3], [](int* p){ delet[] p; });

3.封装default_delete
template<typename T>
shared_ptr<T> make_shared_my(size_t size) {
	return shared_ptr<T>(new T[size], std::default_delete<T[]>());
}

4. struct自定义删除器,重载()
template< typename T >
struct array_deleter{
  void operator ()( T const * p) { 
    delete[] p; 
  }
};
std::shared_ptr<int> sp(new int[10], array_deleter<int>());

shared_from_this

this的智能指针叫shared_from_this()
std::enable_shared_from_this<T>类中有一个weak_ptr在监视this智能指针,当调用shared_from_this方法时,会调用内部weak_ptr的lock()方法

class A : public std::enable_shared_from_this<A> {
	std::shared_ptr<A> getSelf() {
		return shared_from_this();
	}
};

需要注意的

  • 1) 不要使用原始指针直接初始化多个shared_ptr。
    他们的内存计数不共享,达不到自动释放内存的目的。

  • 2) 不要在函数实参中创建shared_ptr
    函数参数计算顺序不同可能会内存泄露。

  • 3) 避免循环引用。
    A,B类中都有一个对方的智能指针。导致永远无法释放内存。

unique_ptr

不允许赋值,但可以通过std::move转移资源

	std::unique_ptr<int> up(new int(10));
	std::unique_ptr<int> up2 = std::move(up);
	// std::unique_ptr<int> up2 = up; error 不能用来复制
	std::cout << "up2 = " << *up2 << std::endl;

删除器 语法和shared_ptr不同

指定时需要确认类型
std::unique_ptr<int, void(*)(int *)> ptr(new int(2), [](int *p) { delete *p;} );

如果需要使用捕获列表:(因为lambda表达式只有在捕获列表空时,才能转换为函数指针)
std::unique_ptr<int, std::function<void(int *)> ptr(new int(2), [&](int *p) { delete *p;} );

自己写删除器
struct array_deleter_int {
	void operator ()(int const* p) {
		std::cout << "array_deleter_int" << std::endl;
		delete[] p;
	}
	array_deleter_int() {
		std::cout << " array_deleter_int constructor" << std::endl;
	}
};
std::unique_ptr<int, array_deleter_int> up3(new int(2));

weak_ptr

作为一个旁观者来监视shared_ptr中管理的资源是否存在。

基本用法

1. use_count() 
std::shared_ptr<int> sp(new int[10]);
std::weak_ptr<int> wp(sp);
std::cout << "wp.use_count() = " << wp.use_count();

2.expired()判断资源是否被释放
true--被释放了,weak_ptr无效

3.lock()获取监视的shared_ptr
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值