C++智能指针

前言

C++ 标准模板库 STL(Standard Template Library) 一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已将其摒弃,并提出了 unique_ptr 替代 auto_ptr。虽然 auto_ptr 已被摒弃,但在实际项目中仍可使用,但建议使用更加安全的 unique_ptr,后文会详细叙述。shared_ptr 和 weak_ptr 则是 C+11 从准标准库 Boost 中引入的两种智能指针。此外,Boost 库还提出了 boost::scoped_ptr、boost::scoped_array、boost::intrusive_ptr 等智能指针,虽然尚未得到 C++ 标准采纳,但是在开发实践中可以使用。

一 auto_ptr

auto_ptr 同样是 STL 智能指针家族的成员之一,由 C++98 引入,定义在头文件。其功能和用法类似于 unique_ptr,由 new expression 获得对象,在 auto_ptr 对象销毁时,他所管理的对象也会自动被 delete 掉。

下面是一些成员函数及其简介

  1. get:得到对象类管理的对象指针
  2. operator*:得到管理的对象
  3. operator->:等价于(*class).,用于获取对象的某个成员
  4. release:将管理对象的指针返回并设置类内指针为null
  5. operator= :相当于调用release之后将返回值构造为新的类初始化左边的类,Release and copy auto_ptr
  6. reset:若无参数直接释放当前对象否则用参数重新设置当前值,无返回值

下面是一个小例子

#include <iostream>
#include <memory>
int main() 
{
	/*
		get:得到对象类管理的对象指针
		operator*:得到管理的对象
		operator->:等价于(*class).,用于获取对象的某个成员
		release:将管理对象的指针返回并设置类内指针为null
		operator= :相当于调用release之后将返回值构造为新的类初始化左边的类,Release and copy auto_ptr
		reset:若无参数直接释放当前对象否则用参数重新设置当前值,无返回值
	*/
	std::auto_ptr<int> a;
	a.reset(new int);//reset:当前对象否则用参数重新设置当前值,无返回值
	*a = 1;
	cout << "a:" << *a << endl;//	operator*:得到管理的对象
	*a = 2;
	std::auto_ptr<int> b;
	b = a;//operator= :相当于调用release之后将返回值构造为新的类初始化左边的类,
	if (a.get())//get:得到对象类管理的对象指针 
	{
		cout << "a:" << *a << endl;
	}
	cout << "b:" << *b << endl;
	*b = 3;
	int *c = b.release();//release:将管理对象的指针返回并设置类内指针为null
	if (a.get())
	{
		cout << "b:" << *b << endl;
	}
	*c = 4;
	cout << "c:" << *c << endl;
	std::auto_ptr<int> d;
	d.reset(c);
	*d = 5;
	if (d.get())
	{
		cout << "d:" << *d << endl;
	}
	cout << "c:" << *c << endl;
	d.reset();//reset:若无参数直接释放,无返回值
	if (d.get())
	{
		cout << "d:" << *d << endl;
	}
	getchar();
	return 0;
}

二.unique_ptr

unique_ptr 由 C++11 引入,旨在替代不安全的 auto_ptr。unique_ptr 是一种定义在头文件中的智能指针。它持有对对象的独有权——两个unique_ptr 不能指向一个对象,即 unique_ptr 不共享它所管理的对象。它无法复制到其他 unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库 (STL)算法。只能移动 unique_ptr,即对资源管理权限可以实现转移。这意味着,内存资源所有权可以转移到另一个 unique_ptr,并且原始 unique_ptr 不再拥有此资源。实际使用中,建议将对象限制为由一个所有者所有,因为多个所有权会使程序逻辑变得复杂。因此,当需要智能指针用于存 C++ 对象时,可使用 unique_ptr,构造 unique_ptr 时,可使用 make_unique Helper 函数。

相比于auto_ptr,其可以在编译期间合理确定智能指针对象作为右值时的合法性,只有作为临时右值才合法否则报错

unique_ptr<int> getUnique(int parm)
{
	unique_ptr<int> temp(new int(parm));
	return temp;
}

int main()
{
	unique_ptr<int> a; //创建空智能指针
	a.reset(new int); //绑定动态对象  
	*a = 1;
	cout << "a:" << *a << endl;
	*a = 2;
	unique_ptr<int>b = std::move(a);//所有权转移(通过移动语义),u_s所有权转移后,变成“空指针” 
	if (a.get())
	{
		cout << "a:" << *a << endl;
	}
	cout << "b:" << *b << endl;
	*b = 3;
	unique_ptr<int> c;
	c.reset(b.release());//所有权转移
	if (b.get())
	{
		cout << "b:" << *b << endl;
	}
	cout << "c:" << *c << endl;

	//unique_ptr<int> d = c; //编译出错,已禁止拷贝
	//unique_ptr<int> d(c); //编译出错,已禁止拷贝
	//unique_ptr<int> d;
	//d = c;//编译出错,已禁止赋值
	unique_ptr<int> d = getUnique(1);//临时正确
	getchar();
	return 0;
}

三 shared_ptr

明天再写

上一篇:「进击Redis」十五、奇妙的 Redis HyperLogLog


下一篇:PHP使用array_unique对二维数组去重处理