一、unique_ptr
unique_ ptr实现了独享被管理对象指针的概念,这意味这它可确保一个对象和其对应的资源同一时间只被一个unique_ ptr对象拥有。一旦拥有者 被销毁或者变成empty或者开始拥有另一个对象的地址,先前拥有的那个对象就会被销毁,其任何相应资源亦会被释放。
一、unqieue——ptr特性
1、unique_ptr对象不能进行复制操作只能进行移动操作。
2、unique是独特的、唯一的意思,故名思议,unique_ptr可以\"独占\"地拥有它所指向的对象。
3、unique_ptr和shared_ptr类型指针有很大的不同: shared_ptr 允许多个指针指向同一对象,而unique_ptr在某一时刻只能有一个指针指向该对象(两个unique_ptr 不能指向同一个对象)。
4、unique_ptr对象中保存指向某个对象的指针,当它本身被删除或者离开其作用域时会自动释放其指向对象所占用的资源。
二、如何使用
1.创建unique_ptr
想要创建unique_ptr,需要将一个new操作符返回的指针传递给unique_ptr的构造函数。
int main()
{
unique_ptr<int>up1(new int(10));
return 0;
}
2.无法使用拷贝构造和赋值操作
unique_ptr是没有拷贝构造和赋值函数的,把这两个函数已经删除。
示例:
int main()
{
unqiue_ptr<int>a1(new int(10));
unique_ptr<int>a2(a1);//err
unique_ptr<int>a3;
a3=a1;//err
}
3、可以进行移动构造和移动赋值
unique_ptr不能和其他指针共享,只能将资源转移,所以是std::move()可以让它达到目的
示例
int main()
{
std::unique_ptr<int>a1(new int(10));
std::unique_ptr<int>a2=std::move(a1);//移动赋值
std::unique_ptr<int>a3(std::move(a2));//移动构造
return 0;
}
4.可以从函数中返回一个unique_ptr
虽然不支持拷贝操作,但可以从一个函数中返回一个唯一性智能指针。
unique_ptr<int>fun(int num)
{
unique_ptr<int>op(new int(num));
return op;
}
int main()
{
int s=1;
unique_ptr<int>a1=fun(s);
return 0;
}
三、模拟实现unique_ptr
template<typename _Ty>
class my_unique_ptr
{
private:
_Ty* _Ptr;
public:
typedef _Ty* pointer;
typedef _Ty element_type;
my_unique_ptr(_Ty* p=nullptr):_Ptr(p){}
my_unique_ptr(my_unique_ptr&&_Y)
{
_Ptr=_Y._Ptr;
_Y._Ptr=nullptr;
}//模拟移动构造
private:
my_unique_ptr(const my_unique_ptr&)=delete;//模拟唯一性,就是让其无法使用拷贝和赋值构造
my_unique_ptr& operator=(const my_unique_ptr&)=delete;
}
int main()
{
my_unique_ptr<int>a1(new int(10));
my_unique_ptr<int>a2(move(a1));
return 0;
}
四、unique_ptr的使用场景
1、保证动态资源的释放
在使用普通的指针指向堆区连续空间时,如果忘记delete,那么会导致内存泄漏,使用unique_ptr可以让堆区空间自动析构。
int main()
{
int *p=new int [10];//忘记delete就会内存泄漏
//程序结束时自动析构动态内存
std::unique_ptr<int>nums(new int[10]);
return 0;
}
2、在容器中保存指针
只能使用移动构造和移动赋值
int main()
{
vector<unique_ptr<int>> vec;
unique_ptr<int>a1(new int(5));
vce.push_back(move(a1));
return 0;
}
3、管理动态数组
unique_ptr提供了多种版本,即:除了有可以管理单个对象的,还有管理一组队象的版本(模板特化)。
int main()
{
unique_ptr<int[]>a1(new int[10]);
return 0;
}