Effective C++——条款15(第3章)

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

Provide access to raw resources in resources-managing classes

资源管理类(resource-managing classes)很棒.它们是对抗资源泄露的堡垒.在一个良好的环境中将依赖这样的classes来处理和资源之间的所有互动.而不是直接处理原始资源,但这个环境并不完美,许多API直接涉及资源,因此有时只能绕过资源管理对象直接访问原始资源(raw resources).

例如,条款13导入一个观念:使用智能指针如auto_ptr或tr1::shared_ptr保存factory函数如createInvestment的调用结果:

std::tr1::shared_ptr<Investment> pInv(createInvestment()); 

假设希望以某个函数处理Investment对象,像这样:

int daysHeld(const Investment* pi);            // 返回投资天数 

如果这样调用它:

int days = daysHeld(pInv);                    // 错误 

却通不过编译,因为daysHeld需要的是Investment*指针,传给它的却是个类型为tr1::shared_ptr<Investment>的对象.

这时候需要一个函数将RAII class 对象(本例为tr1::shared_ptr)转换为其所含的原始资源(本例为底部的Investment*).有两个做法可以达成目标:显式转换和隐式转换.

tr1::shared_ptr和auto_ptr都提供一个get成员函数,用来执行显式转换,即它会返回智能指针内部的原始指针(的副本):

int days = daysHeld(pInv.get());            // 将pInv内的原始指针传给daysHeld 

就像(几乎)所有智能指针一样,tr1::shared_ptr和auto_ptr也重载了指针取值操作符(operator->和operator*),它们允许隐式转换至底部原始指针.

注意:

API往往要求访问原始资源(raw resources),所以每一个RAII class 都应该提供一个"取得其所管理的资源"的办法.

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-03 14:03:21

Effective C++——条款15(第3章)的相关文章

Effective C++ 条款15、16 在资源管理类中提供对原始资源的访问||成对使用new 与 delete要采取相同形式

1.在资源管理类中提供对原始资源的访问     前几个条款很棒,它们是对抗资源泄露的壁垒,但很多APIs直接指向 资源,这个时候,我们需要直接访问原始资源.     这里,有两种方法解决上述问题,我们可将RAII对象转换为原始资源.通过 显式转换与隐式转换.     通常,tr1:: shared_ptr 和 auto_ptr 都提供一个get成员函数,用来执行显式转换,也就是返回智能指针内部的原始指针的复件.因为它也重载了指针取值操作符* –>.当然也可以通过隐式转换为底部原始指针.     

Effective C++——条款14(第3章)

条款14:    在资源管理类中小心copying行为 Think carefully about copying behavior in resource-managing classes 条款13导入这样的观念:"资源取得时机便是初始化时机"(Resource Acquisition Is Initializaiton,RAII),并以此作为"资源管理类"的脊柱,也描述了auto_ptr和tr1::shared_ptr如何将这个观念表现在heap-based资源

Effective C++——条款13(第3章)

第3章    资源管理 Resource Management 所谓资源就是,一旦用了它,将来必须还给系统.C++程序中最常使用的资源就是动态内存分配(如果分配内存从来都增归还,会导致内存泄露).其他常见的资源还有文件描述符(file descriptors),互斥锁(mutex locks),图形界面中的字型和笔刷,数据库连接,以及网络sockets.不论哪一种资源,重要的是,不再使用它时,必须将它还给系统. 条款13:    以对象管理资源 Use objects to manage res

Effective C++——条款5(第2章)

第2章    构造/析构/赋值运算 Constructors,Destructors,and Assignment Operator 几乎每一个 class 都会有一个或多个构造函数,一个析构函数,一个copy assignment 操作符. 条款05:    了解C++默默编写并调用哪些函数 Know what functions C++ silently writes and calls 什么时候empty class 不再是个empty class 呢?当C++处理过它之后.如果自己没有声

effective stl 条款15 小心string实现的多样性

实际上每个string实现都容纳了下面的信息: ● 字符串的大小,也就是它包含的字符的数目. ● 容纳字符串字符的内存容量.(字符串大小和容量之间差别的回顾,参见条款14.) ● 这个字符串的值,也就是,构成这个字符串的字符 另外,一个string可能容纳 ● 它的配置器的拷贝.对于为什么这个域是可选的解释,转向条款10并阅读关于这个古怪的管理分配器的规则.依赖引用计数的string实现也包含了 ● 这个值的引用计数 ● string对象的大小可能从1到至少7倍char*指针的大小.● 新字符串

Effective C++——条款9(第2章)

条款09:    绝不在构造和析构过程中调用 virtual 函数 Never call virtual functions during construction or destruction 不应该在构造函数和析构函数期间调用 virtual 函数,因为这样的调用不会带来预想的结果. 假设有个 class 继承体系,用来模塑股市交易如买进,卖出的订单等等.这样的交易一定要经过审计,所以每当创建一个交易对象,在审计日志中也需要创建一笔适当记录.下面是一个看起来颇为合理的做法: class Tr

Effective C++——条款7(第2章)

条款07:    为多态基类声明 virtual 析构函数 Declare destructors virtual in polymorphic base classes 设计以下时间基类TimeKeeper: class TimeKeeper { public: TimeKeeper(); ~TimeKeeper(); }; class AtomicClock : public TimeKeeper { ... }; class WaterClock : public TimeKeeper {

Effective C++——条款6(第2章)

条款06:    若不想使用编译器自动生成的函数,就该明确拒绝 Explicitly disallow the use of compiler-generated functions you do not want. 在某些情况下,希望保持对象的唯一性,不想让对象有其他副本.如下: class HomeForSale { ... }; HomeForSale h1; HomeForSale h2; HomeForSale h3(h1); // 企图拷贝h1,不应该通过编译 h1 = h2; //

Effective C++ 条款15

在资源管理类中提供对原始资源的访问 前面两节都在讨论如何管理资源,一般情况下,使用资源管理类来屏蔽原始资源,对抗内存泄露等问题,避免使用原始资源.这样我们就无法直接访问原本的原始资源. 毕竟程序在有些时候是需要操纵原始资源的,许多APIs要求使用原始资源. 为了能操纵原始资源,我们要怎么做? 还好,shared_ptr和auto_ptr都提供一个get函数,用于执行这样的显示转换.这时如果在调用API时,如下: shared_prt<Investment> pInv=(createInvest