您的位置:首页 > 编程语言 > C语言/C++

《Effective C++ 改善程序与设计的55个具体做法》——第三章笔记

2015-03-19 20:02 507 查看
资源管理

读这章的时候发现之前对auto_ptr的理解有误,所以找了一些书重新看了一下智能指针模板相关的知识,先把这些基本知识附上。

auto_ptr是C++98中提出的,C++11中将其摒弃,同时提出了unique_ptr和shared_ptr。三者都定义了类似指针的对象,可以将new获得的地址赋值给对象,智能指针过期后,析构函数将使用delete释放内存,无需手动释放。

要创建智能指针,需包含头文件memory:

#include <memory>

using namespace std;

auto_ptr<int> pi(new int);

所有智能指针类都有explicit构造函数,不允许隐式类型转换:

shared_ptr<double> pd;

double *p_veg = new double;

pd = p_veg;  // 不允许

pd = shared_ptr<double>(p_veg);  //允许

注意:不要用非堆内存构造智能指针!!!

赋值上的区别:策略不同

1、所有权概念,对特定对象,只能有一个指针可以拥有它,赋值操作会转让所有权(auto_ptr和unique_ptr都是这样)

2、引用计数(shared_ptr是这样)

拷贝构造也是这样。

所有权转让后,原智能指针指向的为空,再次使用会有问题。

unique_ptr直接在编译阶段就禁止p1 = p2;这种赋值,不会等到运行时崩溃;

unique_ptr允许函数返回值的赋值,因为函数返回值是个临时对象,很快被销毁,即赋值右值是临时的,编译器允许。

unique_ptr<int> p1(new int);

unique_ptr<int> p2;

p2 = p1;  //不允许

unique_ptr<int> p3;

p3 = unique_ptr<int>(new int);  // 允许,临时对象转让后被销毁

容器对象建议不使用auto_ptr,可以使用unique_ptr,因为编译时有错误告警。

auto_ptr使用的是delete,不能用于数组,shared_ptr也不能用于数组。

unique有两个版本,所以可以用于数组。

条款13:以对象管理资源

获得资源后立刻放进管理对象内,资源取得时机便是初始化时机。

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

auto_ptr和shared_ptr在复制行为上的区别

不可用于数组分配。

条款14:资源管理类中小心copying行为

策略:

1、禁止复制

2、对底层资源祭出引用计数法

3、复制底部资源,深度拷贝

4、转移底部资源的拥有权

复制RAII对象必须一并复制它所管理的资源,资源的复制行为决定了RAII对象的复制行为。

条款15:在资源管理类中提供对原始资源的访问

RAII不是为了封装,而是为了资源释放

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

条款16:成对使用new和delete,要采取相同形式

new对应delete,new[ ]对应delete[ ] 

条款17:以独立语句将new的对象置入智能指针

如果不这样,一旦发生异常,有可能导致难以察觉的资源泄露。

考虑如下代码:

processWidget( shared_ptr<Widget>( new Widget ),  priority( ) ); //有问题

编译器中,参数入栈的顺序不固定。如果先new,再执行priority(),再讲资源放入shared_ptr,如果priority中出现异常,内存泄露。

应该如下处理:

shared_ptr<Widget> pw(new Widget);

processWidget( pw,  priority( ) );
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: