C++Primer : 第十二章 : unique_ptr类

unique_ptr类:某个时刻只能有一个unique_ptr指向一个给定对象,当unique_ptr被销毁时,它所指向的对象也被销毁。
与shared_ptr不同,没有类似make_shared的标准库函数返回一个unique_ptr。当我们定义一个unique_ptr时,需要将其绑定到一个new返回的指针上。类似shared_ptr,初始化unique_ptr必须采用直接初始化形式:

unique_ptr<double> p1;    //可以指向一个double的unique_ptr
unique_ptr<int> p2(new int(42));  //p2指向一个值为42的int

由于一个unique_ptr拥有它指向的对象,因此unique_ptr不支持普通的拷贝或赋值操作:

unique_ptr<string> p1(new string("SARS"));
unique_ptr<string> p2(p1);     //错误:unique_ptr不支持拷贝
unique_ptr<string> p3;
p3 = p2;                       //错误:unique_ptr不支持赋值

unique_ptr操作

unique_ptr<T> u1     //空unique_ptr,可以指向类型为T的对象,u1会使用delete来释放它的指针
unique_ptr<T, D> u2  //u2会使用一个类型为D的可调用对象来释放它的指针
unique_ptr<T, D> u(d)  //用类型为D的对象d代替delete
u = nullptr          //释放u指向的对象,将u置为空
u.release()          //u放弃对指针的控制权,返回指针,并将u置为空
u.reset()            //释放u指向的对象
u.reset(q)           //如果提供了内置指针q,令u指向这个对象,否则将u置空

虽然不能拷贝或赋值unique_ptr,但可以通过调用release或reset将指针的所有权从一个(非const)unique_ptr转移给另一个unique_ptr:

unique_ptr<string> p2(p1.release());   //p1被置空,所有权从p1转移给p2
unique_ptr<string> p3(new string("Trex"));
//将所有权从p3转移给了p2
p2.reset(p3.release());   //reset释放了p2原来指向的内存

通常release会切断unique_ptr和它原来管理对象间的联系。release返回的指针通常被用来初始化另一个智能指针或给另一个智能指针赋值。但是,如果我们不用另一个智能指针来保存release返回的指针,程序就需要自己负责资源的释放:

p2.release();    //错误:p2不会释放内存,而且我们丢失了指针
auto p = p2.release();   //正确:但必须记得delete(p)

传递unique_ptr参数和返回unique_ptr
不能拷贝unique_ptr的规则有一个例外;我们可以拷贝或赋值一个将要被销毁的unique_ptr。最常见的例子是从函数返回一个unique_ptr:

unique_ptr<int> clone(int p){
	//正确:从int*创建一个unique_ptr<int>
	return unique_ptr<int>(new int(p));
}

还可以返回一个局部对象的拷贝

unique_ptr<int> clone(int p){
	unique_ptr<int> ret(new int(p));
	return ret;
}

向unique_ptr传递删除器
我们必须在尖括号中unique_ptr指向类型之后提供删除器类型。在创建或reset一个这种unique_ptr类型的对象时,必须提供一个指定类型的可调用对象(删除器):

//p指向一个类型为objT的对象,并使用一个类型为delT的对象释放objT对象
//它会调用一个名为fcn的delT类型对象
unique_ptr<objT, delT> p(new objT, fcn);
发布了75 篇原创文章 · 获赞 4 · 访问量 2023

猜你喜欢

转载自blog.csdn.net/CLZHIT/article/details/104055591