智能指针是现代 C++ 编程中一个绕不开的话题,WebRTC 也有一套使用智能指针的指南。鉴于 WebRTC 属于 Chromium 的一部分,所以这其实也是 Chromium 使用智能指针的指南。
WebRTC 中最常用的智能指针分别是 std::unique_ptr 和 rtc::scoped_refptr ,前者用于独占资源,后者用于引用计数。如果读者熟悉 C++ 11,就会发现 rtc::scoped_refptr 和 std::shared_ptr 很像,但 WebRTC(以及 Chromium)并没有使用 std::shared_ptr 。
个人技术博客: fuqifacai.github.io
更多技术资讯下载: 2img.ai
相关配图由微信小程序【字形绘梦】免费生成

对象所有权和调用约定
这部分内容译自 Chromium C++ style guide。建议读者结合原文观看。
当一个函数将裸指针或者智能指针作为参数时,需要遵循如下约定。这里我们假定参数类型为 T 且参数名为 t 。
- 如果这个函数不会修改
t的所有权,则将其声明为T*。调用方需要保证t的存活时间足够长,使之在整个函数调用过程中都是有效的。除非在极个别情况下,比如使用 STL 的算法和匿名表达式处理智能指针的容器,你可能必须将参数声明为const std::unique_ptr<T>&;其他情况下不要这么做。 - 如果这个函数需要取得没有被引用计数(non-refcounted)的对象的所有权,则将其声明为
std::unique_ptr<T>。 - 如果这个函数(至少在某些时候)需要使用到被引用计数(refcounted)的对象,则将其声明为
scoped_refptr<T>。这样调用方既可以选择通过std::move(t)将该对象的所有权转移给这个函数,也可以选择直接传递t从而仍然持有该对象的引用。 - 简而言之,这个函数应该永不取得参数类型为裸指针的参数的所有权,并且需要将常量引用(const ref)作为参数的情况也非常罕见。
关于函数返回值的约定也差不多,不过有一点不太一样:
- 当且仅当调用方不需要接管对象的所有权时,才返回裸指针。
- 当函数需要移交(handing off)所有权时,按值(by value)返回
std::unique_ptr<T>或者scoped_refptr<T>。 - 不同点在于,当函数需要保持对象的所有权时,应该返回
const scoped_refptr<T>&,这样调用方就不必强行持有该对象的引用(而是持有scoped_refptr<T>的引用)。这有效减少了该对象的引用计数,以及编译出的二进制尺寸。
不过在上述约定出现前已经存在大量的 Chromium 代码了。一些函数已经取得了参数类型为 T* 的参数的所有权,或者将参数类型声明为 const scoped_refptr<T>& 而不是 T* ;或者为了避免 C++ 11 之前的引用丢失(refcount churn)问题,其返回值为 T* 而不是 scoped_refptr<T> 。如果你看到了类似的代码,请尝试清理它们,或者至少不要再传播类似的写法。
剩余内容需解锁后查看
Paragoger衍生者AI训练营。发布者:稻草人,转载请注明出处:https://www.shxcj.com/archives/6699