Chromium的智能指针/引用计数/Callback/Bind

这四个东西对使用者来说不难,看懂代码注释里的例子即可,预计1小时左右看懂全部。要去理解其设计思想的话最需要掌握的是模板类的使用,但一般使用者完全不用关心怎么设计的。

使用者的学习路径:

1.智能删除指针scoped_ptr

用作对普通指针的转储,防止忘记delete或不知道哪里delete。它跟引用计数没有关系。

头文件的注释就是使用示例

http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/scoped_ptr.h

template <class T, class D = base::DefaultDeleter<T> > class scoped_ptr

其中Deleter可以被替换,默认的Deleter区分是要delete普通指针还是指针数组,或者用free函数删除malloc的内存。

2.ScopedVector

http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/scoped_vector.h

在析构时会delete其元素的vector,知道它的行为即可。

3.带引用计数的类

http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/ref_counted.h

为了避免模板类的代码膨胀,引入基类base::subtle::RefCountedBase。基类很简单,就是最基本的引用计数,带AddRef和Release函数。

模板类template <class T> class RefCounted : public subtle::RefCountedBase相对地就只在Release函数内做特殊处理:delete static_cast<const T*>(this)

另外RefCountedThreadSafeBase和模板类RefCountedThreadSafe是线程安全的版本。

4.引用计数的智能指针scoped_refptr

同在ref_counted.h里定义,对RefCounted的子类做引用。scoped_refptr就是构造时调用RefCounted子类的AddRef函数和析构时Release,并提供了操作符的重载。

5.WeakPtr

弱引用指针,用作传递指针但不想更换owner的情况,即明确知道谁去释放但其它引用者不确定其时机,用弱引用指针可随时知道其是否已delete。

http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/weak_ptr.h

看文件里的注释即可。

6.Callback

对函数的闭包封装,头文件的注释就是使用示例

http://src.chromium.org/viewvc/chrome/trunk/src/base/callback.h

要注意注释里提到的对传入参数的要求。Callback最多提供带7个参数的函数封装,其协作类非常多但都不需要去理解。

(理解设计的提示:非常多的模板类,用作抽象各种各样的函数签名;有很多的辅助类和typedef,最好自己整理成图来看清它们的关系)

7.Bind

对Callback的便捷封装,Bind就是返回Callback对象。

http://src.chromium.org/viewvc/chrome/trunk/src/base/bind.h

看看头文件知道它是个模板函数并为不同参数个数做了重载就行了。

(理解设计的提示:查看http://src.chromium.org/viewvc/chrome/trunk/src/base/bind_internal.h文件的注释)



对scoped_ptr的理解:

没有引用计数的类,使用scoped_ptr<class T, class D>。这个模板类中的D是指Deleter,代表如何删除T。引入Deleter最简单的原因就是对数组需要使用delete[]操作符,实际上有4个默认的Deleter。

3个Deleter都是通过重载括号运算符来执行实际的delete操作,而常量长度的数组指针是不允许使用智能指针的,这里也声明出来,能在编译阶段就排除错误。

除了DefaultDeleter,还有一些特殊的Deleter,如disk cache使用的EntryDeleter(disk_cache.h),字节对齐的内存使用的AlignedFreeDeleter(aligned_memory.h),他们都有自己的括号运算符重载实现,因为这是scoped_ptr模板类要求的的方式。

scoped_ptr还有个基类template <class T, class D> class scoped_ptr_impl,它实现了scoped_ptr的核心功能,这样抽离出来是因为有些地方不需要更多的功能。这是模板类,多一个函数就可能多好多个实现。

scoped_ptr_impl定义了内部类Data来继承Deleter,实际就是增加了ptr来保存传入的裸指针(raw pointer / bare pointer)。

struct Data : public D {
    explicit Data(T* ptr_in) : ptr(ptr_in) {}
    Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {}
    T* ptr;
};

Data data_;

scoped_ptr_impl的主要函数:

  explicit scoped_ptr_impl(T* p) : data_(p) { }

  ~scoped_ptr_impl() {
    if (data_.ptr != NULL) {
      // Not using get_deleter() saves one function call in non-optimized
      // builds.
      static_cast<D&>(data_)(data_.ptr);
    }
  }
  void reset(T* p) {
    // This is a self-reset, which is no longer allowed: http://crbug.com/162971
    if (p != NULL && p == data_.ptr)
      abort();
    T* old = data_.ptr;
    data_.ptr = NULL;
    if (old != NULL)
      static_cast<D&>(data_)(old);
    data_.ptr = p;
  }
  T* get() const { return data_.ptr; }
  D& get_deleter() { return data_; }
  const D& get_deleter() const { return data_; }
  void swap(scoped_ptr_impl& p2) {
    using std::swap;
    swap(static_cast<D&>(data_), static_cast<D&>(p2.data_));
    swap(data_.ptr, p2.data_.ptr);
  }
  T* release() {
    T* old_ptr = data_.ptr;
    data_.ptr = NULL;
    return old_ptr;
  }

scoped_ptr是独立的模板类

template <class T, class D = base::DefaultDeleter<T> > class scoped_ptr

template <class T, class D> base::scoped_ptr<T[], D>

它有唯一的成员变量

base::internal::scoped_ptr_impl<element_type, deleter_type> impl_
即是组合scoped_ptr_impl,而不是用继承(也就是桥接模式)。impl有的函数,scoped_ptr都有,并多了重载运算符,以便使用者能直接使用智能指针做其它操作:

typedef T element_type

内存释放的流程:scoped_ptr析构=>impl_析构=>调用deleter=>delete element_type


对引用计数的理解:

有引用计数的智能指针则简单多了:

其中T是本身实现了引用计数的类。

为了避免模板类,引入基类:

基类都是这老一套,用变量保存引用数,没啥说的。

模板类:

template <class T>
class RefCounted : public subtle::RefCountedBase {
 public:
  RefCounted() {}

  void AddRef() const {
    subtle::RefCountedBase::AddRef();
  }

  void Release() const {
    if (subtle::RefCountedBase::Release()) {
      delete static_cast<const T*>(this);
    }
  }

 protected:
  ~RefCounted() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
};

参考:

http://dev.chromium.org/developers/coding-style/important-abstractions-and-data-structures

转载请注明出处:http://blog.csdn.net/hursing

时间: 2024-10-25 03:24:37

Chromium的智能指针/引用计数/Callback/Bind的相关文章

智能指针学习笔记

1. 介绍 本文介绍智能指针的使用.智能指针是c++ 中管理资源的一种方式,用智能指针管理资源,不必担心资源泄露,将c++ 程序员 从指针和内存管理中解脱出来,再者,这也是c++发展的趋势(这话不是我说的,见<Effective c++>和<c++实践编程>),应该认真学习一下. 智能指针中,最有名的应该数auto_ptr,该智能指针已经被纳入标准库,只需要包含<memory>头文件即可以使用,另外,TR1文档定义的shared_ptr和weak_ptr也已经实现(我用

C++引用计数的智能指针有效回收方法

引用计数指针是否能有效地回收,对系统意外关机之后数据的恢复来说至关重要,关键是要避免对象复制. 怎样从灾难性故障中,恢复一个长期运行.系统级的后台守护进程或者服务,在如今的软件设计过程中,已成为了一个重要的考虑因素.当这些软件是由C++语言编成,并使用了引用计数的智能指针时,那么,智能指针的有效回收,对系统是否具有可伸缩级的恢复能力.甚至正确地继续未完成的操作来说,都显得至关重要. 在本文中,描述了一种方法,可从关机之后的软件恢复中,有效地回收引用计数指针,而且此方法在内存占用方面也非常高效,这

引用计数我不怕之智能指针

前言 使用引记数,就算是再历害的高手也难免会出错.而一但出错了,之后再去查问题可就相当的困难了.正如我曾经看到,有一段代码是这样的: m_spView->Release();m_spView->Release();m_spView->Release();   看到这段代码,就知道引用计数出问题了.他想通过这种方式,把多出来的计数Release掉.但这么做能解决问题吗?答案是不能,这样的代码还可能造成严重的稳定性问题.解决引用计数问题,除了要了解引用计数规则外,我们还提昌要用智能指针.智能

引用内部函数绑定机制,R转义字符,C++引用,别名,模板元,宏,断言,C++多线程,C++智能指针

 1.引用内部函数绑定机制 #include<iostream> #include<functional>   usingnamespacestd; usingnamespacestd::placeholders;   //仿函数,创建一个函数指针,引用一个结构体内部或者一个类内部的共有函数 structMyStruct {    voidadd(inta)    {        cout <<a <<endl;    }    voidadd2(in

智能指针与弱引用详解_Android

在android 中可以广泛看到的template<typename T> class Sp 句柄类实际上是android 为实现垃圾回收机制的智能指针.智能指针是c++ 中的一个概念,因为c++ 本身不具备垃圾回收机制,而且指针也不具备构造函数和析构函数,所以为了实现内存( 动态存储区) 的安全回收,必须对指针进行一层封装,而这个封装就是智能指针,其实说白了,智能指针就是具备指针功能同时提供安全内存回收的一个类.当然,智能指针的功能还不只这些,想了解更多大家可以去研究下- 智能指针有很多实现

智能指针与弱引用详解

在android 中可以广泛看到的template<typename T> class Sp 句柄类实际上是android 为实现垃圾回收机制的智能指针.智能指针是c++ 中的一个概念,因为c++ 本身不具备垃圾回收机制,而且指针也不具备构造函数和析构函数,所以为了实现内存( 动态存储区) 的安全回收,必须对指针进行一层封装,而这个封装就是智能指针,其实说白了,智能指针就是具备指针功能同时提供安全内存回收的一个类.当然,智能指针的功能还不只这些,想了解更多大家可以去研究下- 智能指针有很多实现

大型项目开发:谨慎使用智能指针

智能指针使用上的问题 智能指针的使用太普遍了,它让程序员摆脱了内存管理的恶梦,但实际上智能指针本身也可能引入另一个恶梦.主要包括两个问题点: 性能问题.因为需要引入一些变量(bookkeeping),甚至在多线程下的一些互斥操作,它所带来的性能开销往往比想像的要高.比如以智能指针作为函数参数以及返回值时. 对象释放的时机不明确.比如std::auto_ptr,总让人感觉不明不白.而有时一些循环引用,又会导致内存泄露. 所以即便有了智能指针,程序员还是要认真考虑使用它们的时机. 智能指针的本质是所

Google C++编程风格指南(四):智能指针和其他C++特性

1.对于智能指针,安全第一.方便第二,尽可能局部化(scoped_ptr): 2.引用形参加上const,否则使用指针形参:3.函数重载的使用要清晰.易读:4.鉴于容易误用,禁止使用缺省函数参数(值得商榷):5.禁止使用变长数组:6.合理使用友元-- Google特有的风情 Google有很多自己实现的使C++代码更加健壮的技巧.功能,以及有异于别处的C++的使用方式. 1.智能指针(Smart Pointers) 如果确实需要使用智能指针的话,scoped_ptr完全可以胜任.在非常特殊的情况

C++ 智能指针深入解析

以下是对C++中智能指针的使用进行了详细的分析介绍,需要的朋友可以参考下   1. 为什么需要智能指针?简单的说,智能指针是为了实现类似于Java中的垃圾回收机制.Java的 垃圾回收机制使程序员从繁杂的内存管理任务中彻底的解脱出来,在申请使用一块内存区域之后,无需去关注应该何时何地释放内存,Java将会自动帮助回收. 但是出于效率和其他原因(可能C++设计者不屑于这种傻瓜氏的编程方式),C++本身并没有这样的功能,其繁杂且易出错的内存管理也一直为广大程序员所诟 病. 更进一步地说,智能指针的出