C++内存管理学习笔记(4) (四)

2014-11-24 00:56:18 · 作者: · 浏览: 16
函数。

1: class SmartItem: public SmartPointer 2: { 3: public: 4: explicit SmartItem (int i) 5: : SmartPointer (new Item (i)) {} 6: };
  为每一个类提供一个Smart Pointer真的值得吗?说实话——不!他很有教学的价值,但是一旦你学会如何遵循第一规则的话,你就可以放松规则并使用一些高级的技术。这一技术是让SmartPointer的构造函数成为public,但是只是是用它来做资源转换(Resource Transfer)。我的意思是用new操作符的结果直接作为SmartPointer的构造函数的参数,像这样:

1: SmartPointer item (new Item (i));
  这个方法明显更需要自控性,不只是你,而且包括你的程序小组的每个成员。他们都必须发誓出了作资源转换外不把构造函数用在人以其他用途。幸运的是,这条规矩很容易得以加强。只需要在源文件中查找所有的new即可。

看到这里,你肯定和我一样会有很多疑问,不要着急,慢慢来看。下面以c++中的auto_ptr来说明。


2.4 auto_ptr类

首先,什么是smart pointer? 智能指针(Smart pointer)是一种抽象的数据类型。在程序设计中,它通常是经由类模板(class template)来做,借由模板(template)来达成泛型,通常借由类型(class)的析构函数来达成自动释放指针所指向的存储器或对象。

什么是类模板和泛型编程?---《C++ primer》
1 类模板(class template)
模板定义:模板就是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数, 从而实现了真正的代码可重用性。模版可以分为两类,一个是函数模版,另外一个是类模版。
函数模板的一般形式如下:

1: Template 2: 返回类型 函数名(形参表) 3: {//函数定义体 }
说明: template是一个声明模板的关键字,表示声明一个模板关键字class不能省略,如果类型形参多余一个 ,每个形参前都要加class <类型 形参表>可以包含基本数据类型可以包含类类型.

定义一个类模板:

1: template 2: class 类名{ 3: // 类定义...... 4: };
说明:其中,template是声明各模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个。


2泛型编程
泛型编程就是以独立于任何特定的方式编写代码。 泛型编程最初诞生于C++中,,由Alexander Stepanov和David Musser创立。目的是为了实现C++的STL(标准模板库)。其语言支持机制就是模板(Templates)。

泛型编程的核心活动是抽象:将一个特定于某些类型的算法中那些类型无关的共性抽象出来,比如,在STL的概念体系里面,管你是一个数组还是一个链表,反正都是一个区间,这就是一层抽象。管你是一个内建函数还是一个自定义类,反正都是一个Callable(可调用)的对象(在C++里面通过仿函数来表示),这就是一层抽象。泛型编程的过程就是一个不断将这些抽象提升(lift)出来的过程,最终的目的是形成一个最大程度上通用的算法或类。

说了这么一大堆,肯定会茫茫然,这是正常的,想研究泛型编程的请仔细阅读《C++ Primer》一书。这里主要是为解释smart pointer而做的铺垫。

在C++ primer上面提供了了两种解决方案,设置拥有权的转移和使用引用计数的方式。针对这个两个解决方案,出现了两种风格的智能指针,STL中的auto_ptr属于拥有权转移指针,boost中的shared_ptr属于引用计数型(boost里面的智能指针有6个,这里只是其中一个)。

本文这里主要讲解其中的auto_ptr类方式,为了更好的理解后续笔记的内容提前做一个铺垫。

(1)auto_ptr类

C++标准模板库有一个模板类,叫做auto_ptr,其作用就是提供这种封装。它是上一节介绍的RAII规则的例子。auto_ptr类是接收一个类型形参的模板,它为动态分配的对象提供异常安全。我们来看一个例子,auto_ptr的部分实现,说明什么是auto_ptr:

1: template class auto_ptr 2: { 3: T* ptr; 4: public: 5: explicit auto_ptr(T* p = 0) : ptr(p) {} 6: ~auto_ptr() {delete ptr;} 7: T& operator*() {return *ptr;} 8: T* operator->() {return ptr;} 9: // ... 10: };
auto_ptr is a simple wrapper around a regular pointer. It forwards all meaningful operations to this pointer (dereferencing and indirection). Its smartness in the destructor: the destructor takes care of deleting the pointer.(auto_ptr 只是简单的包含一个常规指针T* p,它(间接的和非关联的)指向所有有意义的操作。在析构函数中更加智能化:析构函数负责删除指针。)

(2)auto_ptr操作

auto_ptr ap; 创建名为 ap 的未绑定的 auto_ptr 对象

auto_ptr ap(p); 创建名为 ap 的 auto_ptr 对象,ap 拥有指针 p 指向的对象。该构造函数为explicit

auto_ptr ap1(ap2); 创建名为 ap1 的 auto_ptr 对象,ap1 保存原来存储在ap2 中的指针。将所有权转给 ap1,ap2 成为未绑定的auto_ptr 对象

ap1 = ap2 将所有权 ap2 转给 ap1。删除 ap1 指向的对象并且使 ap1指向 ap2 指向的对象,使 ap2 成为未绑定的

~ap 析构函数。删除 ap 指向的对象

*ap 返回对 ap 所绑定的对象的引用

ap-> 返回 ap 保存的指针

ap.reset(p) 如果 p 与 ap 的值不同,则删除 ap 指向的对象并且将 ap绑定到 p

ap.release() 返回 ap 所保存的指针并且使 ap 成为未绑定的

ap.get() 返回 ap 保存的指针

注意:
auto_p