unique_ptr的用法

1.从一个unique_ptr直接赋值给另一个unique_ptr是合法的,比如

ptr = std::unique_ptr<ClassA>(new ClassA)

但是下面的写法不对:
ptr1=ptr2;
出处 Nicolai Josuttis <c++ 标准库> 第二版,中文版 102页
2.但是将一个unique_ptr作为输入参数传给函数时,可以采用如下两种办法:
2-1)左值引用。在调用函数后,unique_ptr指针仍然占有指向的资源。

std::unique_ptr<...>  up(...);
void func(std::unique_ptr<...> &);
.....
func(up);

2-2)

std::unique_ptr<classX>  up(...);
void func(classX &);
.....
func(*up);

甚至还有一种右值引用的办法。采用这种办法,在调用函数后,unique_ptr指向的资源就被释放了

std::unique_ptr<...>  up(...);
void func(std::unique_ptr<...> );
.....
func(std::move(up));

出处 Nicolai Josuttis <c++ 标准库> 第二版5.2节,中文版 102页
3.假如一个函数的返回值是unique_ptr,则在函数结尾直接写return unique_ptr<…>;即可。如下:

std::unique_ptr<...> func()
{
	std::unique_ptr<...> up(...);
	return up;
}

调用这个函数时,理论上要在函数外面包括一个std::move:

std::unique_ptr<..> up = std::move(func());

但是实际上,可以省去move函数,原因是c++11规定,编译器应自动尝试加上move.
出处 Nicolai Josuttis <c++ 标准库> 第二版5.2节,中文版 103页
4.也可以用make_unique直接给unique_ptr赋值
5.对数组来说,假如unique_ptr的尖括号<>包括的类型是数组,则即使没有明确指明deleter,unique_ptr销毁时,数组仍会以delete []的方式释放。
假如尖括号<>包括的不是数组,但实际上unique_ptr管理的是数组,则应将一个能够释放数组的deleter分配给unique_ptr.
c++11提供std::default_delete函数满足这个要求。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智能指针 智能指针shared_ptr的⽤法 的⽤法   为了解决C++内存泄漏的问题,C++11引⼊了智能指针(Smart Pointer)。   智能指针的原理是,接受⼀个申请好的内存地址,构造⼀个保存在栈上的智能指针对象,当程序退出栈的作⽤域范围后,由于栈上的变 量⾃动被销毁,智能指针内部保存的内存也就被释放掉了(除⾮将智能指针保存起来)。   C++11提供了三种智能指针:std::shared_ptr, std::unique_ptr, std::weak_ptr,使⽤时需添加头⽂件<memory>。   shared_ptr使⽤引⽤计数,每⼀个shared_ptr的拷贝都指向相同的内存。每使⽤他⼀次,内部的引⽤计数加1,每析构⼀次,内部的引⽤ 计数减1,减为0时,删除所指向的堆内存。shared_ptr内部的引⽤计数是安全的,但是对象的读取需要加锁。 1. shared_ptr的基本⽤法 初始化   可以通过构造函数、std::make_shared<T>辅助函数和reset⽅法来初始化shared_ptr: #include "stdafx.h" #include <iostream> #include <future> #include <thread> using namespace std; class Person { public: Person(int v) { value = v; std::cout << "Cons" <<value<< std::endl; } ~Person() { std::cout << "Des" <<value<< std::endl; } int value; }; int main() { std::shared_ptr<Person> p1(new Person(1));// Person(1)的引⽤计数为1 std::shared_ptr<Person> p2 = std::make_shared<Person>(2); p1.reset(new Person(3));// ⾸先⽣成新对象,然后引⽤计数减1,引⽤计数为0,故析构Person(1) // 最后将新对象的指针交给智能指针 std::shared_ptr<Person> p3 = p1;//现在p1和p3同时指向Person(3),Person(3)的引⽤计数为2 p1.reset();//Person(3)的引⽤计数为1 p3.reset();//Person(3)的引⽤计数为0,析构Person(3) return 0; }   注意,不能将⼀个原始指针直接赋值给⼀个智能指针,如下所⽰,原因是⼀个是类,⼀个是指针。 std::shared_ptr<int> p4 = new int(1);// error   reset()包含两个操作。当智能指针中有值的时候,调⽤reset()会使引⽤计数减1.当调⽤reset(new xxx())重新赋值时,智能指针⾸先是⽣ 成新对象,然后将就对象的引⽤计数减1(当然,如果发现引⽤计数为0时,则析构旧对象),然后将新对象的指针交给智能指针保管。 获取原始指针   std::shared_ptr<int> p4(new int(5)); int *pInt = p4.get(); 指定删除器   智能指针可以指定删除器,当智能指针的引⽤计数为0时,⾃动调⽤指定的删除器来释放内存。std::shared_ptr可以指定删除器的⼀个原 因是其默认删除器不⽀持数组对象,这⼀点需要注意。   2. 使⽤shared_ptr需要注意的问题   但凡⼀些⾼级的⽤法,使⽤时都有不少陷阱。 不要⽤⼀个原始指针初始化多个shared_ptr,原因在于,会造成⼆次销毁,如下所⽰: int *p5 = new int; std::shared_ptr<int> p6(p5); std::shared_ptr<int> p7(p5);// logic error 不要在函数实参中创建shared_ptr。因为C++的函数参数的计算顺序在不同的编译器下是不同的。正确的做法是先创建好,然后再传 ⼊。 function(shared_ptr<int>(new int), g()); 禁⽌通过shared_from_this()返回this指针,这样做可能也会造成⼆次析构。 避免循环引⽤。智能指针最⼤的⼀个陷阱是循环引⽤,循环引⽤会导致内存泄漏。解决⽅法是AStruct或BStruct改为weak_ptr。 struct AStruct; struct BStruct; struct AStruct { std::shared_ptr<BStruct> bPtr; ~AStruct() {

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值