levy5307 / blog

https://levy5307.github.io/blog/
MIT License
0 stars 0 forks source link

Google Refptr #13

Open levy5307 opened 4 years ago

levy5307 commented 4 years ago

https://levy5307.github.io/blog/google-refptr/

最近工作中发现了一个关于智能指针的=运算符重载的经典代码实现,记录一下:

scoped_refptr& operator=(std::nullptr_t) { reset(); return this; } // Sets managed object to null and releases reference to the previous managed // object, if it existed. void reset() { scoped_refptr().swap(this); }

scoped_refptr& operator=(T p) { return this = scoped_refptr(p); } // Unified assignment operator. scoped_refptr& operator=(scoped_refptr r) noexcept { swap(r); return *this; } void swap(scopedrefptr& r) noexcept { std::swap(ptr, r.ptr_); }

可以只看operator=(std::nullptr_t), 由于将this赋值给null,所以this需要释放。此时operator=这个函数不好实现,因为如果在函数退出前释放的话,释放后的任何操作都相当于操作了已释放对象(可参考附录1我在pr中的描述)。

这里的google的实现是:将this和一个临时变量进行swap, 该临时对象的ptr_为null,交换后临时对象的ptr变成了this->ptr,this->ptr_变成了null,这是前提。然后经典的来了,当reset函数退出时,

临时变量退出了其作用区域,会被释放,根据指针的特性,其对应的其ptr_指向的空间也会释放,由于此时临时对象的ptr是this->ptr,所以reset退出时,实际释放的是this->ptr_。

下面的几个函数原理是一样的,这里就不解释了

具体代码文件:https://chromium.googlesource.com/chromium/src/+/master/base/memory/scoped_refptr.h

附录1:https://github.com/XiaoMi/rdsn/pull/361