模板类
定义一个如下的UniquePtr模板类,使得可以使用UniquePtr托管各种类型的指针。类中包含一个T *ptr用于存储要托管的指针。
template<typename T>
class UniquePtr {
// ...
private:
T *ptr;
};
//构造函数
UniquePtr(T *ptr = nullptr) : ptr(ptr) {}
//析构
~UniquePtr() {
if (ptr) {
delete ptr;
ptr = nullptr;
}
}
//禁用拷贝构造和赋值运算符
//由于UniquePtr对象托管的指针是独享的,
//拷贝构造和赋值操作会有歧义,因此使用如下方式禁用。
UniquePtr(const UniquePtr &p) = delete;
UniquePtr &operator=(const UniquePtr &p) = delete;
//移动构造函数
UniquePtr(UniquePtr &&p) noexcept: ptr(p.ptr) {
p.ptr = nullptr;
}
移动构造函数
UniquePtr支持移动构造。使用移动构造函数构造新对象后,原对象所托管指针将被转移到新对象上
从下面代码段可以看出左边的新对象构造以后,所托管的指针将与右边的原对象脱离,右对象的ptr_置nullptr。这也是为什么该类智能指针被称为unique_ptr的原因。因为所托管的指针只能由一个UniquePtr对象独享。
// Move constructor.
UniquePtr(UniquePtr &&p) noexcept: ptr(p.ptr) {
p.ptr = nullptr;
}
类成员访问运算符(->)
为了让使用UniquePtr对象就像使用所托管指针一样,可以直接使用->访问托管指针对应类中成员,需要对operator->进行重写
// Return the stored pointer.
T *operator->() const noexcept { return ptr; }
析构函数为什么要调用delete
贴一下源码
~unique_ptr() noexcept
{
auto& __ptr = std::get<0>(_M_t);
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
}
unique_ptr(非静态类)在调用构造函数之前,不占用堆栈空间,unique_ptr在调用构造函数时,需要传入一个参数,这个参数通常是new出来的,因此需要delete