C++的垃圾回收——以对象管理内存

 

1、以对象管理内存(Use Objects to manager resources.

这一条款主要说的是如何进行动态内存申请释放。

RAII原则:

Ø       获得资源后立刻放进管理对象内;

Ø       管理对象运用析构函数确保资源被释放;

我自己也写过一个动态申请释放的类。这个类的一个假设是,一个资源在被申请后会马上被使用,而在函数返回后就需要释放。为此我写了一个基类,每个资源类都要继承这个基类。每个资源子类的构造函数和析构函数都是private,这样就杜绝了newdelete操作。申请新的对象通过类的static函数来实现,不提供释放函数接口。基类中有一个static list,基类的构造函数会将this指针添加到这个list中。基类每隔5个循环就遍历一下list,看有没有待释放对象,如果有,则直接进行释放。

标准程序库auto_ptr类指针对象

应该是一个模板。

std::auto_ptr<Point> pInv(new Point(1));

Point是类指针对象指向的类。

pInv是类指针的变量名称。他后面的()中填写的类指针指向的类的引用。

void r_test()

{

    std::auto_ptr<Point> pInv(new Point(1));

 

    pInv->GetX();

}

之后,pInv就可以直接作为Point指针来使用。只不过它是局部变量,在函数返回是会释放。释放的时候,会进行Point的析构操作。

使用auto_ptr一定要防止多个指针指向一个对象,这样会造成多次释放。所以他有一个性质:若通过copy构造函数或者copy赋值函数复制他们,则他们本身会变成NULL,而复制所得指针会获得资源的唯一所有权。

注意:auto_ptrcopy赋值函数和copy构造函数的风险非常大。要少使用。

引用计数型智慧指针(RCSP

这个在linux好像没有(需要包含头文件#include <tr1/memory>)。

注意:

为了防止资源泄漏,请使用RAII(起源获取时机便是初始化时机——资源在构造期间获得,在析构期间释放)对象,他们在构造函数中获得资源,并在析构函数中释放资源。(使用的模板技术)

两个常被使用的RAIIclass分别是tr1::shared_ptratuo_ptr。前者通常是较佳选择,因为copy比较直观。若选择atuo_ptr,复制操作会使他(被复制物)指向NULL

 

2、在资源管理类中小心copying行为(Think carefully about copying behavior in resource-managing classes.

如果tr1::shared_ptratuo_ptr不适合作为资源管理类,则需要构造自己的资源管理类。

自己设计资源管理类时,也需要遵循RAII原则:

特别需要注意的一个问题是,RAII对象被复制时,会发生什么事情:

1、  禁止复制

2、  对底层资源使用引用计数法(reference count)通常,资源管理类只要内含一个tr1::shared_ptr成员变量,RAII就可以实现reference-counting copying行为。

tr1::shared_ptr默认情况下在删除的时候会delete相应的对象,但是,可以在构造时指定所谓的删除器,那是一个函数或者函数对象(而不是单纯的对象?什么是函数对象?),当应用次数为零时便被调用(此机制并不存在于auto_ptr——他总是将指针删除)。

3、  复制底部资源。也就是进行所谓的深度拷贝。

4、  转移资源的拥有权——就像auto_ptr一样。

注意:

复制RAII对象的时候必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的拷贝行为。

普遍而常见的RAIIclasses copying行为是:抑制copying,施行引用计数法。

 

3、  在资源管理类中提供对原始资源的访问(Provide access to raw resources in resource-managing classes.

RAII class需要一个函数可以见RAII classes 对象转化为其所内含的原始资源。

显示转换:

tr1::shared_ptrauto_ptr都提供get成员函数。用来执行显示转换。

另外,他们都提供了operator->operator*操作符,可以执行隐式转换。

尽量使用显示转换。

get函数与封装相矛盾,但是问题并不大。因为RAIIclass 主要的作用是为了资源释放。

“设计良好的类,会隐藏用户不需要看到的部分,当备妥客户需要看到的东西。”

注意:

APIs往往要求访问原始资源,所以每一个RAIIclass应该提供一个取得其所管理资源的方法。

对原始资源的访问可能经由显示转换和隐式转换,一般而言显示转换比较安全,但隐式转换相对比较方便。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值