写点什么

C++ 实现 unique_ptr

作者:行者孙
  • 2021 年 12 月 14 日
  • 本文字数:1181 字

    阅读完需:约 4 分钟

现代 C++的说和重要基本思想是 RAII(Resource Acquisition Is Initialization). 把资源的生存期交给一个对象管理,在对象析构的时候把负责管理的资源给释放。 C 和 C++ 比较特殊的一点(但是这却是 C/C++之所以强大和高性能的原因之一)是没有 Python、Java 等的垃圾回收功能,使用 malloc 和 new 申请的内存需要调用对应的 free 和 delete 方法来释放内存,否则将会造成“内存泄露”。基于 RAII 的思想,C++11 推出了智能指针(unique_ptrshared_ptrweak_ptr) , 申请的内存交给智能指针管理,当智能指针的生存期结束,会“智能”的释放掉内存,避免了程序员忘记 delete 造成 bug。


这篇不讲解智能指针的用法,而是应该去自己实现 unique_ptr注:在实际使用的时候使用标准库的智能指针,而不应该用自己造的,本 DIY 系列只是为了通过造一些玩具来达到练习的目的。

实现 unique_ptr

namespace diy {template <typename T>class unique_ptr { private:  T *ptr_;
public: explicit unique_ptr(T *ptr) : ptr_(ptr) {} unique_ptr(unique_ptr &&other) noexcept : ptr_(nullptr) { this->swap(other); }; unique_ptr &operator=(unique_ptr &&other) noexcept { this->swap(other); return *this; } unique_ptr(const unique_ptr &) = delete; unique_ptr &operator=(const unique_ptr &) = delete;
~unique_ptr() { delete ptr_; ptr_ = nullptr; }
void swap(unique_ptr &other) noexcept { using std::swap; swap(ptr_, other.ptr_); }
T *get() const { return ptr_; }
T &operator*() const { return *ptr_; }
T *operator->() const { return ptr_; }
// in conditional expression explicit operator bool() { return ptr_; }};} // namespace diy
复制代码


源码和测试用例见我的github

要点

  1. 在 unique_ptr 的生存期结束时,析构时释放内存

  2. move 语义,实现 move-constructor 和 move-assignment-operator

  3. 禁止拷贝对于 unique_ptr 只应该有 move 语义,而没有 copy 语义。 因为如果两个 unqiue_ptr 保存的是同一个原始指针,在析构的时候分别调用析构函数,将会出现 double delete 的问题;或者一个对象已经 delete 了而另外的还在使用,也会产生错误。

  4. move 和 swap 都应该 noexcept 标识了 noexcept, 该函数是不抛异常的, 使用如 std::vector 这样的 stl 容器来存放 unique_ptr 时将会调用 move 构造函数,否则可能使用 copy (开销大), 参考 《C++ Core Guideline 》C66

  5. 对于 get(), operator->(), operator*() 需要必要的 const (Const Correctness)

Ref

  1. https://en.cppreference.com/w/cpp/language/raii

  2. https://lokiastari.com/blog/2014/12/30/c-plus-plus-by-example-smart-pointer/

  3. https://codereview.stackexchange.com/questions/163854/my-implementation-for-stdunique-ptr/163857

  4. 参考阅读llvm 的stl源码

发布于: 1 小时前阅读数: 8
用户头像

行者孙

关注

Nothing replaces hard work 2018.09.17 加入

充满好奇心,终身学习者。 博客:https://01io.tech

评论

发布
暂无评论
C++实现unique_ptr