unique_ptr
它是一个独占型指针,不允许共享指针内容,也不允许智能指针赋值操作。
unique_ptr<int> ptr(new int(2));
//unique_ptr<int> ptr1 = ptr; //error 不可复制
unique_ptr<int> ptr2 = std::move(ptr); //ok 只可以移动不可复制
我们可以通过实现一个make_unique_ptr来深入理解一下这个智能指针
template<class T, class...Args> inline
typename std::enable_if<!is_array<T>::value, unique_ptr<T>>::type
make_unique_ptr(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
//支持动态数组
template<class T> inline
typename std::enable_if<is_array<T>::value && extent<T>::value == 0, unique_ptr<T>>::type
make_unique_ptr(size_t size)
{
typedef typename std::remove_extent<T>::type U;
return unique_ptr<T>(new U[size]());
}
//过滤掉定长数组的情况 长度固定
template<class T, class...Args>
typename enable_if<extent<T>::value != 0, void>::type
make_unique_ptr(Args&&...) = delete;
如果不是数组则直接创建unique_ptr,若是数组则判断是否为定长数组(因为不能make_unique_ptr
指向数组
std::unique_ptr<int[]> ptr4(new int[10]);
ptr4[9] = 9;
注意:std::shared_ptr
定义删除器
std::unique_ptr<int, void(*)(int*)> ptr6(new int(2), [](int*p) {delete p; });
unique_ptr指定删除的时候需要确定删除器类型,如上面表达式。
上面的写法在lambda没有捕获变量的情况下是可以直接转换为函数指针的,一旦捕获了就无法转换了。
如果想要unique_ptr的删除器支持lambda,可以这样写:
std::unique_ptr<int, std::function<void(int*)>> ptr7(new int(2), [&](int*p) {delete p; });
当然也可以自定义删除结构体,实现operation()函数即可。