C++学习 二、unique_ptr使用
前言
本篇继续C++11智能指针学习,unique_ptr
unique_ptr概述
与shared_ptr类似,unique_ptr也有自动释放空间的特性,不需要手动释放空间和删除指针。
从名字上可以看出,unique_ptr独享内部指针和内存空间的所有权,当unique_ptr对象被销毁时,其独占的内存空间和内部指针都会被释放和销毁。
同时,同一个指针不能被两个unique_ptr对象关联,否则就会出现double free问题。
创建unique_ptr对象
创建空unique_ptr对象
std::unique_ptr<int> p1();
std::unique_ptr<int> p2(nullptr);
通过堆指针创建unique_ptr对象
std::unique_ptr<int> p3(new int);
注意:与shared_ptr类不同,unique_ptr类没有拷贝构造函数!以下创建方法报错:
//std::unique_ptr<int> p4(p3); //error!
注意:与shared_ptr类类似,unique_ptr类也没有构造函数隐式转换,以下创建方法报错:
//std::unique_ptr<int> p4 = new int; // error!
通过std::make_unique()函数创建unique_ptr对象
注意:C++11没有提供make_unique函数,但C++14提供了。
std::make_unique<int> p4 = std::make_unique<int>(134);
unique_ptr成员函数
与shared_ptr类似,unique_ptr类也有其成员函数,并且许多功能相同。
reset(T *p)
释放当前内部指针指向的内存空间,并把指针变为nullptr;如果参数p为普通指针,则释放后把内部指针变为p。
get()
获得内部指针。
swap(std::unique_ptr<T> &p)
把两个unique_ptr对象的内部指针做交换。
release()
切断对象与内部指针的联系,不会释放内存空间。返回内部指针,对象的内部指针变为nullptr。
get_deleter()
获得对象的删除器。
unique_ptr的操作符
unique_ptr类重载了指针运算符*,->
std::unique_ptr<int> p(new int(1));
*p;
也重载了赋值运算符=,但是只能用于右值为nullptr或者左值为空的情况。
std::unique_ptr<int> pp;
pp = std::unique_ptr<int>(new int(5));
pp = nullptr;
unique_ptr也有>,<,==,!=等比较运算符,但没有算术运算符号;此外,重载了[]运算符用于数组操作。
创建unique_ptr数组
与shared_ptr数组创建需要提供删除器不同,unique_ptr数组创建时可以省略提供删除器(自动使用默认数组删除器):
std::unique_ptr<int []> pVec(new int[5]())
unique_ptr比shared_ptr更适合创建数组。
可以直接使用[]来获得数组成员:
int vec1 = pVec[1]; // 0
测试代码
#include <iostream>
#include <memory>
class A;
class B;
class A
{
public:
std::unique_ptr<B> b_;
public:
A(){
std::cout << "construct A" << std::endl;
}
~A(){
std::cout << "destroy A" << std::endl;
}
};
class B
{
public:
std::unique_ptr<A> a_;
public:
B(){
std::cout << "construct B" << std::endl;
}
~B(){
std::cout << "destroy B" << std::endl;
}
};
int main(int argc, char **argv) {
// *** construct unique ptr *** ///
int *a = new int(1);
std::unique_ptr<int> p1(a);
// std::unique_ptr<int> p2(p2); // error! No copy constructor
//std::unique_ptr<int> p3(a);
std::unique_ptr<int> p3(new int(323));
std::unique_ptr<int> p4 = std::make_unique<int>(134);
std::unique_ptr<int> p5;
p5 = std::unique_ptr<int>(new int(567));
std::unique_ptr<int[]> pVec(new int[5]());
std::cout << *p5 << std::endl;
std::cout << (p4 >= p4) << std::endl;
std::unique_ptr<A[]> aVec(new A[8]);
std::unique_ptr<B[]> bVec(new B[8]);
return 1;
}
后记
下篇记录weak_ptr