WebRTC 中的 RefCountedObject 解析

    引用计数功能在对象的回收中至关重要,java 中,每个对象都会有引用计数,当引用计数为 0 时,对象将被标记会可回收,等待着垃圾回收机制进行回收。C++中没有垃圾自动回收的机制,但是不妨碍我们想办法自己实现这种引用计数的功能。在 Webrtc 中,RefCountedObject 类就是承担了这样的功能。

template <class T>
class RefCountedObject : public T {
 public:
  RefCountedObject() {}
  template <class P0>
  explicit RefCountedObject(P0&& p0) : T(std::forward<P0>(p0)) {}
  template <class P0, class P1, class... Args>
  RefCountedObject(P0&& p0, P1&& p1, Args&&... args)
      : T(std::forward<P0>(p0),
          std::forward<P1>(p1),
          std::forward<Args>(args)...) {}
  virtual void AddRef() const { ref_count_.IncRef(); }
  virtual RefCountReleaseStatus Release() const {
    const auto status = ref_count_.DecRef();
    if (status == RefCountReleaseStatus::kDroppedLastRef) {
      delete this;
    }
    return status;
  }
  virtual bool HasOneRef() const { return ref_count_.HasOneRef(); }
 protected:
  virtual ~RefCountedObject() {}
  mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
  RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedObject);
};

    代码比较简单,是一个模板类。我注意到这里有个比较高级的用法,RefCountedObject 类继承了 class T。也就是说 RefCountedObject<A>是 A 的一个子类,这样的好处是 A 的代码无需继承 RefCountedObject。但我不是特别喜欢这种代码样式,不符合我们一般人的思维方式。

类中有一个变量 ref_count_,里面封装了 long 型的变量,并且实现了线程安全的加 1 和减 1。

RefCountedObject 只是让类拥有了引用计数的功能,并没有自动回收的功能,或许你看到 Release 函数里有 delete this 的代码,觉得这个就是回收的功能。这样理解好像也没什么问题,但是类 A 中并没有调用 Release,它甚至不知道 RefCountedObject 的存在,那 Release 究竟是在哪被调用呢?因此要实现引用计数自动回收的功能,必须配合 scoped_refptr<>模板类进行使用。

scoped_refptr<A> sa = new RefCountedObject<A>();

    这个语句看起来语法有点问题,等号左边是一个非指针对象 sa,等号右边却是一个 new 的指针对象。想做到这样其实也不难,重载一下 operator=就可以了。

scoped_refptr<T>& operator=(T* p) {

    // AddRef first so that self assignment should work

    if (p)

      p->AddRef();

    if (ptr_)

      ptr_->Release();

    ptr_ = p;

    return *this;

  }

    可以看到,RefCountedObject 中实现的 AddRef 以及 Release 函数是在 scoped_refptr 中被调用的。关于 scoped_refptr,我会在另一篇文章中解析。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值