WebRTC中的scoped_refptr解析

 众所周知,C++中在堆中申请的内存都需要程序员自己手动删除,这是C++容易造成内存泄漏的根本原因。使用过Java的朋友都清楚,Java有完善的内存回收机制,无需程序员调用释放内存的操作。C++里是否能够实现类似Java的自动回收内存的机制呢?答案是肯定的,而Webrtc中的scoped_refptr就是实现类似的功能。

首先我们从这个类的名字入手去理解它的含义。名字由三个单词组成,分别为scope,ref,ptr。

先看ptr,C++程序员都知道这是pointer指针的意思,但是类名中包含指针的语义,这个该如何理解呢?笔者不才,说实话,这个我也是想了好久才弄明白是怎么回事。先说结论吧,在webrtc中,凡是以ptr结尾的类,若以此类创建的非指针对象,均可以当指针对象的语法使用。估计读者有点蒙,下面以实际例子说明。

一般来说,C++中有两种创建对象的方法,一种是创建指针对象

A *a = new A();
a->func();

 另一种是创建非指针对象


A a;
a.func()

    这两种方法创建的对象,对象调用方法的语法是不一样的。一个是以->方式调用,一个是以.方式调用。但是请看:

scoped_refptr<A> temp;
temp->func();

    注意到了吗?temp是以非指针对象的方式创建的,但是它可以使用指针对象的语法调用函数方法。这个是如何实现的呢?这个其实一点也不难,scoped_refptr的代码中实现了operator->的操作符。

T* operator->() const { return ptr_; }

      因此,像这种以ptr结尾的类,最好都以非指针的方式来创建对象。以非指针方式创建对象还有另一个好处,就是当对象离开它所属的作用域时,会自动调用对象的析构函数进行自行销毁。这个也跟接下来要讲的scope单词相关。

     要想弄明白scope的含义,我们要学一个概念,叫RAII。这个概念如果单纯去看这个英文的全名(Resouce Acquisition Is Initialization),会让人莫名其妙,一头雾水。其实就是把一个指向堆内存空间的指针,存放在一个栈空间对象中,通过栈空间对象自动回收的功能,同时回收此指针指向的堆内存的方法。看个简单的例子吧,如果我们在一段作用域代码中创建了一个指针对象,当离开此作用域时,如果该指针没有传递给别的方法时,此时应该显式调用delete对指针进行释放。

A* a = new A();
delete a;
a = NULL;

     虽然对于经验丰富的C++程序员来说,忘记写最后两句的概率并不大,但是这些大量的释放内存的代码嵌在业务代码中也不能忽视。因此就有些人想了个高级的办法把指针的释放封装了起来。做法如下:

首先定义一个类:

class scoped_A{
private:
    A* a;
public:
    scoped_A(A* a){
        this.a = a;
    }
    ~scoped_A(){
        delete a;
        a = NULL;
    }
}

具体用法:


A* a = new A();
scoped_A(a) sa;

或者

scoped_A sa(new A());

    看到了吗?你可以理解为使用一个scoped_A的对象sa把指针对象a包住,当sa离开作用域自动调用scoped_A的析构函数,以达到自动释放a指针的目的。不得不说,这个是很妙的做法。这也是scope的含义,是指这个ptr对象是有范围的,离开了作用域,会自动回收。

    最后来说说ref,ref是引用的意思。在JAVA中,我们经常说一块内存会被多个变量引用,当这块内存没有被任何变量引用的时候,内存将会被垃圾回收机制所回收。在C++中,堆中的一块内存也会被多个指针变量同时引用(指向),有没有办法也像JAVA一样,在这块堆内存没有被任何指针引用时,自动回收呢?这个就要说到Webrtc中的RefCountedObject类了,关于这个类的解释可以看另一篇文章。要想彻底弄懂scoped_refptr,需要两篇文章放在一起看。

    总结:scoped_refptr是一个实现了在C++上自动回收对象内存的功能类。它能够在对象离开作用域时,通过引用计数器来判断是否回收堆中内存,实现了类似Java的垃圾回收的机制。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值