c++11&14-智能指针要点汇总

2020-06-03 15:01:53王振洲

运行结果:

TestA()
TestB()
1 ref a:1
1 ref b:1
~TestA::TestWork()
2 ref a:2
~TestB()
~TestA()

预览
由以上代码运行结果我们可以看到:

所有的对象最后都能正常释放,不会存在上一个例子中的内存没有释放的问题;
ptr_aptr_b在main函数中退出前,引用计数均为1,也就是说,在TestATestB中对std::weak_ptr的相互引用,不会导致计数的增加。在TestB析构函数中,调用std::shared_ptr tmp = m_TestA_Ptr.lock(),std::weak_ptr类型转换成std::shared_ptr类型,然后对TestA对象进行调用。

1.2.3 std::weak_ptr支持的调用

weak_ptr<T> w;	//空weak_ptr可以指向类型为T的对象
weak_ptr<T> w(shared_ptr sp);	//与sp指向相同对象的weak_ptr, T必须能转换为sp指向的类型
w = p;	//p可以是shared_ptr或者weak_ptr,赋值后w和p共享对象
w.reset();	//weak_ptr置为空
w.use_count();	//与w共享对象的shared_ptr的计数
w.expired();	//w.use_count()为0则返回true,否则返回false
w.lock();	//w.expired()为true,返回空的shared_ptr;否则返回指向w的shared_ptr

1.3 std::unique_ptr

uniqut_ptr是一种对资源具有排他性拥有权的智能指针,即一个对象资源只能同时被一个unique_ptr指向。

1.3.1 初始化方式

使用new

T *pT = new T();
std::unique_ptr<T> up1(pT);

通过make_unique

auto pT = make_unique<T>();

通过move()函数

//up也是一个std::unique_ptr<T>指针
unique_ptr<T> up1 = std::move(up); 

1.3.2 unique_ptr不能被复制或者拷贝

unique_ptr<T> up(new T()); //ok
unique_ptr<T> up1(up); //error, can not be copy
unique_ptr<T> up2 = up; //error, can not be assigned

1.3.3 unique_ptr可以移动赋值或者移动拷贝

unique_ptr<T> pT(new T());
unique_ptr<T> pT2 = std::move(pT);	//移动赋值,此时pT被销毁,为空
unique_ptr<T> pT3(std::move(pt2)); //移动拷贝,此时pT2被销毁,为空

1.3.4 unique_ptr可以作为函数的返回值

unique_ptr<T> GetPtr(); //function getthe unique pointer
unique_ptr<T> pT = GetPtr(); // ok

1.3.5 使用范例

#include <iostream>
int main()
{
	std::unique_ptr<int> pInt;
	pInt.reset(new int());
	int *p = pInt.release(); //释放所有权
	//由于unique_ptr有std::unique_ptr<T[]>的重载函数,所以它可以用来管理数组资源
	std::unique_ptr<int[]> pArray(new int[3]{1,3,3}); 
}

2. 智能指针小结

可以看出,智能指针其实是std::shared_ptr和std::unique_ptr, std::shared_ptr可以有多个引用对象,但不能互相引用,而std::unique_ptr只能有一个引用,不能赋值或者拷贝,但可以移动赋值和移动拷贝,std::weak_ptr实际上是对std::shared_ptr的补充,它并不能对对象进行具体的操作。