Conclusion for Resource Management
来源:互联网 发布:淘宝能在1688 编辑:程序博客网 时间:2024/05/22 23:31
条款13:
1.再看工厂函数
我们使用一个投资行为库,其中各式各样的投资行为继承自一个root class Investment:
class Investment{};进一步假设这个程序库通过工厂函数(条款7)供应我们特定的Investment对象:
Investment* createInvestment(); //返回指针,指向Investment继承体系的动态分配对象。调用者有责任删除它。
void fun() { Investment* pInv=CreateInvestment(); …… delete pInv;//释放资源 }看起来正常,但是若在delete语句之前程序结束(比如return或异常)。
2.我们需要将资源放进对象内,当控制流离开f,该对象的析构函数会自动释放 哪些资源。
auto_ptr是一个类,用来实现对动态分配对象的自动释放。auto_ptr在构造时获取对某个对象的所有权,在析构时释放该对象。
void fun(){std::auto_ptr<Investment> pInv = CreateInvestment();}这样离开函数时,资源被自动回收。
3.auto_ptr有一个不寻常的性质:若通过copy构造函数或copy assignment操作符复制它们,它们会变成null,而复制所得的指针将取得资源的唯一拥有权。如果让多个auto_ptr指向同一对象,则对象会被删除一次以上。
void f(){ std::auto_ptr<Investment> pInv(createInvestment()); std::auto_ptr<Investment> pInv2(pInv); //pInv 变为Null pInv指向对象 pInv = pInv2 //pInv 指向对象 pInv2变为NULL}
auto_ptr不适用有复制的容器身上。
4.shared_ptr作用如同指针,但会记录有多个shared_ptr共同指向同一个对象,这便是引用计数,计数为0时,会被自动删除。void f(){ std::tr1::shared_ptr<Investment> pInv(createInvestment()); std::tr1::shared_ptr<Investment> PInv2(pInv); //PInv和PInv2同时指向一个对象。 PInv = Pinv2;}5.auto_ptr和tr1::shared_ptr都在其析构函数内做delete而不是delete []动作。因此不要在动态分配而得的array身上使用auto_ptr和shared_ptr。
虽然下面也可以通过编译,但是不要这样用:
std::auto_ptr<std::string> aps(new std::string[10]);可以用vector和string取代动态分配而得的数组。
条款14:
1.为了确保不会忘记将一个被锁住的Mutex解锁,可以建立一个class用来管理锁。
void lock(Mutex* pm); void unlock(Mutex* pm); class Lock{ public: explicit Lock(Mutex* pm) : mutexPtr(pm) { lock(mutexPtr); //获得资源 } ~Lock(){ unlock(mutexPtr); } //释放资源 private: Mutex *mutexPtr; };Lock的使用如下:
Mutex m; //定义需要的互斥器//...{Lock m1(&m); //锁住互斥器//...} //在区域最末尾,自动解除互斥器锁定
第一种可能:禁止复制
将sopying操作声明为private。
Class Lock:private Uncopyable //禁止复制(条款6){ //……};第二种可能:对底层祭出“引用计数法”,也就是用shared_ptr实现底层。
calss Lock{public:explicit Lock(Mutex* pm):mutexPtr(pm,unlock){ lock(mutexPtr.get());}private:std::tr1::shared_ptr<Mutex> mutexPtr;};注:不用声明析构函数。条款5说个,class析构函数(无论编译器生成还是用户定义)会自动调用其non-static成员变量的析构函数。
条款15:
1.将RAII class对象转换为其所含的原始资源。
shared_prt<Investment> pInv=(createInvestment());但是处理Investment对象的函数像这样:
int daysHeld(const Investment* pi); //返回投资天数下面的调用不能通过编译,因为daysHeld需要的是Investment*指针,传给他的却是个类型为tr1::shared_ptr<Investment>的对象。
int days=daysHeld(pInv);shared_ptr和auto_ptr都提供一个get成员函数,用来执行显示转换,也就是他会返回智能指针内部的原始指针(的复件)
int days=dayHeld(pInv.get());2.就像所有智能指针一样,tr1::shared_ptr和auto_ptr也重载了指针取值操作符(operator->和operator*),它们允许隐式转换至底部原始指针:
class Investment{public:bool isTaxFree() const;//……};Investment* createInvestment(); //factory函数std::tr1::shared_prt<Investment> pi(createInvestment());pi->isTaxFree();//通过operator->访问 (*pi).isTaxFree();//通过operator*访问3.有时候我们必须使用RAII class内的原始资源。做法是提供隐式转换函数。
FontHandle getFont();//C的API。为求简化省略参数 void releaseFont(FontHandle fh); class Font{//RAII class public: explicit Font(FontHandle fh):f(fh) {} ~Font(){releaseFont(f);} private: FontHandle f; };假设有大量与字体相关的C API,它们处理的是FontHandles,那么“将Font对象转换为FontHandle”会是一种很烦繁的需求。Font class可为此提供一个显示转换函数。
class Font{ public: FontHandle get()const{return f;} //…… };不过客户要想使用API就必须调用get。另一种做法是为Font提供隐式转换函数,转型为FontHandle:
class Font{ public: operator FontHandle ()const{return f;}//隐式转换 …… };注:C++可通过operator 隐式转换,格式如下: operator 类型T (),T是要转换到的类型。上面可以使Font隐式转换为FontHandle。
条款16:
1.new 对应delete;new type[]对应delete []。
条款17:
1.C++完成参数的核算顺序不定。
假设两个函数,一个解释优先权,另一个进行带优先权的处理:
int priority();void processWidget(tr1::shared_ptr<Widget> pw, int priority);现在考虑processWidget:
processWidget(new Widget, priority());是的,无法通过编译,构造函数是explicit函数,无法将原始指针隐式转为shared_ptr。下面这样可以编译:
processWidget(tr1::shared_ptr<Widget>(new Widget), priority());可惜这样也可能泄露资源,原因是C++完成参数的核算顺序不定,可能的顺序如下:
执行“new Widget”
调用priority
调用tr1::shared_ptr
如果priority调用异常,“new Widget”返回的指针将会遗失,造成泄漏。
2.避免1中问题很简单,使用分离语句。
tr1::shared_ptr<Widget> pw(new Widget);//在单独语句内以智能指针存储newed所得对象。 processWidget(pw, priority());以上行得通,是因为编译器对于“跨越语句的各项操作”没有重新排列自由。
0 0
- Conclusion for Resource Management
- Slurm - Simple Linux Utility for Resource Management
- Best Practices for YARN Resource Management
- Conclusion for Implementations
- Pattern-Oriented Software Architecture: Patterns for Resource Management, Volume 3
- Item18 Use std::unique_ptr for exclusive-ownership resource management
- conclusion for 6.25-6.29:learning
- Conclusion for Designs and Declarations
- Conclusion
- Conclusion
- C# Resource Management (资源管理器)
- Chapter3: Resource Management
- DRM-Dynamic Resource Management
- 资源管理-Resource management
- Part2:Resource Management/资源管理
- EC之Resource Management
- Custom Resource Management Architecture
- OpenCL resource management
- 第一个Android用例
- [Javascript Data Structures] 二分查找 Binary Search
- HTML5 Cookie总结
- 黑马程序员——java基础---集合--迭代
- Web Services 指南之:Web Services 的组件
- Conclusion for Resource Management
- 缺失值的处理方法
- android读取应用签名信息
- Java 对象特性知识点复习
- bzoj1066 (最大流)
- 操作系统作业动态分区
- C#托管代码与C++非托管代码互相调用
- Android简单实用的交互动画库
- 医学图像分割方法