Chinaunix首页 | 论坛 | 博客
  • 博客访问: 22865
  • 博文数量: 28
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-25 21:56
文章分类

全部博文(28)

文章存档

2015年(28)

我的朋友

分类: C/C++

2015-10-22 14:51:52

原文网址:

WTF是WebKit中重要的C++类库,其中提供了大量实用的模板类,在WebKit的代码中得到广泛运用。在工作之中由于经常用到,在此总结一下,也算留个笔记。


顾名思义,OwnPtr表示“拥有”的意思。“拥有”这一词很玄妙,可能在这儿你还不知道它的深刻含义,没关系,看到RefPtr的时候你就知道了。
WTF::OwnPtr ptr = adoptPtr(new MyClass);

于是名为ptr的OwnPtr就构造好了。当ptr的析构函数被调用时,会立即调用MyClass类的析构函数,释放MyClass实例内存。这有什么用呢?我们来看一段代码。

点击(此处)折叠或打开

  1. MyClass * createInstance() {
  2.     MyClass *ret = new MyClass;
  3.     if (!checkA()) {
  4.        delete ret;
  5.        return NULL;
  6.     }
  7.  
  8.     if (!checkB()) {
  9.        delete ret;
  10.        return NULL;
  11.     }
  12.  
  13.     return ret;
  14. }
上面的代码企图创建在进行checkA和checkB的检查后返回一个新的MyClass实例。看起来并没有什么问题,但如果中间的检查逻辑复杂繁多,那么有可能你会忘了进行 delete ret; 或者重复进行该操作,造成内存泄漏或者Crash。如果用OwnPtr来实现这个,有代码:

点击(此处)折叠或打开

  1. PassOwnPtr createInstance() {
  2.     OwnPtr ret = adoptPtr(new MyClass);
  3.     if (!checkA()) {
  4.        return NULL;
  5.     }
  6.  
  7.     if (!checkB()) {
  8.        return NULL;
  9.     }
  10.  
  11.     return ret.release();
  12. }

这里为什么不需要用delete ret了呢?正是因为OwnPtr帮助你管理了这个指针。我们知道,当这个函数返回的时候,ret的析构函数(记住是OwnPtr的析构)会被调用,这时就会删除新创建的MyClass实例。而最后的ret.release()返回的是PassOwnPtr类型。这代表什么意思呢?这里就要从这个函数的意义来讲了。该函数创建一个新的MyClass实例,要有其它人负责最后释放这个实例。这个叫做“所有权转移”,createInstance函数刚开始构建新实例,所有权还在createInstance函数手里,当它返回的时候,所有权就交出去了。

这一“所有权转移”的过程表现在这个函数里就是,ret为createInstance函数所“拥有的”,当它完成构建后,调用 release 方法释放这个所有权,通过PassOwnPtr转交给其它人。所以这里可以知道,PassOwnPtr是负责“转移所有权的”,要确定所有权,你可以这样调用:

OwnPtr result = createInstance();

adoptPtr

而我们看到的adoptPtr又是干什么的呢?看看函数声明:

template PassOwnPtr adoptPtr(T*);

它接受一个裸指针,构造一个用于所有权转移的PassOwnPtr,然后丢给使用者OwnPtr。记住OwnPtr只接受PassOwnPtr类型的传递。

leakPtr


点击(此处)折叠或打开

  1. MyClass* createInstance() {
  2.     OwnPtr ret = adoptPtr(new MyClass);
  3.     if (!checkA()) {
  4.        return NULL;
  5.     }
  6.  
  7.     if (!checkB()) {
  8.        return NULL;
  9.     }
  10.  
  11.     return ret.leakPtr();
  12. }

继续看以上的函数的另一种实现。如果我们坚持要返回裸指针,怎么办呢?使用leakPtr()来获取。leakPtr顾名思义就是“泄漏”裸指针出来使用。这个函数的作用是取消OwnPtr的管辖,即OwnPtr中的保存的裸指针被置为空,OwnPtr析构的时候不会删除任何东西。这也是所有权转移的一种手段,只是转移到的是一个裸指针,而不再是PassOwnPtr而已。

OwnPtr的常用使用方法


点击(此处)折叠或打开

  1. // 接收一个裸指针并创建为使用OwnPtr管理
  2. OwnPtr a = adoptPtr(new MyClass);
  3.  
  4. // 读取裸指针的值(但不改变任何东西)
  5. MyClass *ptr = a.get();
  6.  
  7. // 引用这个指针(和裸指针一样)
  8. (*a).methodA();
  9.  
  10. // 直接访问这个指针(和裸指针一样)
  11. a->methodA();
No related posts.



阅读(465) | 评论(0) | 转发(0) |
0

上一篇:gcc命令

下一篇:没有了

给主人留下些什么吧!~~