小言_互联网的博客

C++智能指针

298人阅读  评论(0)

C++智能指针

shared_ptr(c++11)

shared_ptr概念


shared_ptr初始化

  • 正确初始化方式
shared_ptr<int> p1;
shared_ptr<int> p2(new int(10));
shared_ptr<int> fun(int value)
{
   
	return shared_ptr<int> (new int(value));
/*make_shared是一个函数模板,
用来从堆中分配并初始化一个对象
,返回指向此对象的shared_ptr*/
shared_ptr<int> p4 = make_shared<int>(100);
}
  • 错误初始化方式
/*shared_ptr<int> fun(int value)
{
	return new int(value);//int没法转成shared_ptr<int>
}*/
说明:make_shared分配内存时,没有办法自定义删除器,所以,如果想自定义删除器,那么就不用该函数。

shared_ptr引用计数

  • 引用计数的增加
  • 引用计数的减少
    • 指向新对象
    • 局部shared_ptr离开其作用域
    • 引用计数为0会自动析构自己所管理的对象

shared_ptr常用操作

  • use_count()
shared_ptr<int> p1(new int(10));
	cout << p1.use_count() << endl;//引用计数为1
	shared_ptr<int> p2(p1);//其实会调用拷贝构造函数,p1,p2的引用计数都会加一
	cout << p1.use_count() << endl;//2
	cout << p2.use_count() << endl;//2
	shared_ptr<int> p3;
	p3 = p2;//会调用拷贝赋值运算符
	cout << p1.use_count() << endl;//3
	cout << p2.use_count() << endl;//3
	cout << p3.use_count() << endl;//3
  • unique()
shared_ptr<int> p1(new int(10));
	if (p1.unique())//成立
	{
   
		cout << "引用计数为一" << endl;
	}
	shared_ptr<int> p2(p1);//其实会调用拷贝构造函数,p1,p2的引用计数都会加一
	if (p1.unique())//不成立
	{
   
		cout << "引用计数为一" << endl;
	}
  • reset()
    • 带参数与不带参数
在这里插入代码片
  • *解引用
在这里插入代码片
  • get()
在这里插入代码片
  • swap()
在这里插入代码片
  • =nullptr
在这里插入代码片
  • 智能指针名字作为判断条件
在这里插入代码片
  • 指定删除器和数组问题
在这里插入代码片

shared_ptr使用说明

  • 使用场景
  • 使用陷阱分析
    • 慎用裸指针
    • 慎用get返回的指针
    • 用enable_shared_from_this返回this
    • 避免循环引用
  • 性能说明
    • 尺寸问题(sizeof)
    • 移动语义
  • 使用建议
  • 自我实现一个shared_ptr
template<class T>
class SmartPtr
{
   
public:
	SmartPtr();
	explicit SmartPtr(T *p);
	~SmartPtr();
	SmartPtr(SmartPtr<T> &s);                
	SmartPtr<T>& operator=(SmartPtr<T> &s);   
private:
	T *ptr;
	int use_count;
};

template<class T>
SmartPtr<T>::SmartPtr():ptr(nullptr),use_count(0)
{
   
	cout << "默认构造函数执行了" << endl;
}

template<class T>
SmartPtr<T>::SmartPtr(T *p):ptr(p),use_count(1)
{
   
	cout << p << endl;
	cout << ptr << endl;
	cout << "构造函数执行了" << endl;
}

template<class T>
SmartPtr<T>::~SmartPtr()
{
   
	/*当引用计数为0时释放内存*/
	if (--(use_count) == 0)
	{
   
		cout << ptr << endl;
		delete ptr;
		ptr = nullptr;
		use_count = 0;
		cout << "析构函数执行了" << endl;
	}
}

template<class T>
SmartPtr<T>::SmartPtr(SmartPtr<T> &s)
{
   
	s.use_count++;
	ptr = s.ptr;
	use_count = s.use_count;
	cout << "拷贝构造函数执行了" << endl;
}

template<class T>
SmartPtr<T>& SmartPtr<T>::operator=(SmartPtr<T> &s)
{
   
	++s.use_count;
	if (--use_count == 0)
	{
   
		delete ptr;
		use_count = 0;
		cout << "拷贝赋值运算符执行了" << endl;
	}
	ptr = s.ptr;
	use_count = s.use_count;
	return *this;
}

weak_ptr(c++11)

weak_ptr介绍

在这里插入代码片

weak_ptr常用操作

  • use_count
  • expired
  • reset
  • lock

weak_ptr尺寸问题(sizeof)

自我实现一个weak_ptr

在这里插入代码片

auto_ptr(c++98)

auto_ptr为什么被放弃(缺点)

  • 不能在容器中保存auto_ptr
  • 不能从函数中返回auto_ptr
  • auto_ptr也是一个独占式指针,但是存在缺陷

unique_ptr(c++11)

概念/初始化方式

  • 概念
  • 初始化方式
    • 子主题 1
    • 子主题 2
    • 子主题 3

unique_ptr常用操作

  • 不支持的操作
在这里插入代码片
  • 移动语义
在这里插入代码片
  • release
在这里插入代码片
  • reset
在这里插入代码片
  • =nullptr
在这里插入代码片
  • 指向一个数组
在这里插入代码片
  • get
在这里插入代码片
  • 解引用*
在这里插入代码片
  • swap
在这里插入代码片
  • 智能指针名字作为判断条件
在这里插入代码片
  • 转换成shared_ptr类型
在这里插入代码片

unique_ptr删除器与尺寸(sizeof)问题

  • 删除器
  • 尺寸问题

自我实现一个unique_ptr

在这里插入代码片

智能指针总结

设计思想

智能指针的选择

  • 要使用多个指向同一个对象的指针时,应该选择shared_ptr
  • 不需要使用多个指向同一个对象的指针时,应该选择unique_ptr

转载:https://blog.csdn.net/qq_38158479/article/details/116464272
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场