effective C++ 读书笔记 条款14 以对象管理资源

如果我们使用一个投资行为的程序库:

#include "stdafx.h"
#include <iostream>
#include <memory>
using namespace std;
class  Investment
{
public:
};
class InvestmentFactory
{
public:
	virtual Investment* createInvestment()
	{
		Investment * inV = NULL;
		return inV;
	}
};
//第一版,这里可能发生内存泄露,比方在调用createInvestmen()之后到delete pInv之间的函数体之间发生了异常或者调用了return等
//那么delete语句将不会被运行,早成内存泄露
void f()
{
	InvestmentFactory fac;
	Investment* pInv = fac.createInvestment();

	delete pInv;
}

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}

//第一版,这里可能发生内存泄露,比方在调用createInvestmen()之后到delete pInv之间的函数体之间发生了异常或者调用了return等

//那么delete语句将不会被运行,早成内存泄露

<span style="color:#3333ff;">void f()
{
	InvestmentFactory fac;
	Investment* pInv = fac.createInvestment();

	delete pInv;
}</span>

//第二版:为了确保createInvestment返回的资源总是被释放,我们须要将资源放进对象内。当控制流离开f,该对象的析构函数会自己主动释放那些资源

//auto_ptr是个类指针对象,也就是所谓的“智能指针”。其析构函数会自己主动对其所指对象调用delete。

<span style="color:#3333ff;">void f()
{
	InvestmentFactory fac;
	std::auto_ptr<Investment> pInv(fac.createInvestment());//调用factory函数,一如既往的使用pInv。经由auto_ptr的析构函数自己主动删除pInv
}</span>

//上面第二版“以对象管理资源”的两个关键想法

1:获得资源后马上放进管理对象:以上代码createInvestmen返回的资源被当做其管理者auto_ptr的初值。

对象资源管理的观念也被称为

资源取得实际便是初始化时机。由于我们总是在获得一笔资源后于允许语句内以它初始化某个管理对象

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

//第二版存在的问题:

//因为auto_ptr被销毁时会自己主动删除它所指之物,所以一定要注意别让多个auto_ptr同一时候指向某一对象。假设真是这样。对象会被删除一次以上,程序

//出现没有定义行为,为了防止这个问题,auto_ptr有一个不平常的性质:若通过copy构造函数或者copy assigment操作符复制他们,他们会变为null

//而复制所得的指针将取得资源的唯一全部权。

auto_ptr<Investmen> pInv1(fac.createInvestment()); pInv1指向资源

auto_ptr<Investment> pInv2(pInv1); pInv2指向资源pInv1为NULL

pInv1 = pInv2; pInv1指向对象,pInv2成为null

//第三版:

<span style="color:#3333ff;">void f()
{
	InvestmentFactory fac;
	std::shared_ptr<Investment> pInv1(fac.createInvestment());//调用factory函数。一如既往的使用pInv,经由shared_ptr的析构函数自己主动删除pInv

	tr1::shared_ptr<Investment> pInv2(pInv1);//pInv1 和 pInv2 指向一个资源对象
	pInv2 = pInv1;//同上,无不论什么改变

	//当pInv1 and pInv2 销毁的时候,它们所指的对象也被自己主动销毁
}</span>

/*

第三版能够正常使用,也是最佳版本号。 可是注意auto_ptr and shared_ptr在析构函数其中都是做的 delete而不是delete[],所以不要把

动态分配而得的array用在auto_ptr and shared_ptr身上。

*/

总结:

为防止资源泄露,请使用对象管理资源,他们在构造函数其中获得资源。并在析构函数其中释放资源

两个经常使用的RAII class 为 tr1::shared_ptr and auto_ptr;第一个是最佳选择由于其copy行为比較直观,若选择auto_ptr复制动作会使得它指向null。

时间: 2024-10-13 14:17:28

effective C++ 读书笔记 条款14 以对象管理资源的相关文章

Effective Java读书笔记(3对于所有对象都通用的方法)

3.1 覆盖equals时请遵守通用约定 什么时候应该覆盖Object.equals()方法呢? 如果类具有自己特有的"逻辑相等"概念(不同于对象等同的概念),而且超类还没有覆盖equals以实现期望的行为,这时我们就需要覆盖equals方法. Object.equals()方法具有自反性.对称性.传递性.一致性和与null比较返回false的特点. 实现高质量equals方法的诀窍: (1)使用==操作符检查"参数是否为这个对象的引用".如果是,则返回true,这

Effective C++ 条款13/14 以对象管理资源 || 在资源管理类中小心拷贝行为

三.资源管理       资源就是一旦你使用了它,将来不用的时候必须归还系统.C++中最常用的资源就是动态内存分配.其实,资源还有 文件描述符.互斥器.图形界面中的字形.画刷.数据库连接.socket等. 1.        以对象管理资源       void f() {     investment *plv = createInvestment();     //这里存在很多不定因素,可能造成下面语句无法执行,这就存在资源泄露的可能.     delete plv; }      这里我们

effective C++ 读书笔记 条款06

条款06:若不想使用编译器自动生成的函数,就该明确拒绝: 直接看代码与注释: #include <iostream> using namespace std; class Test { public: Test() { } ~Test() { } /* void TT() { Test t1; Test t2(t1); } */ private: Test(const Test& test); Test& operator = (const Test& test); }

Effective C++读书笔记(条款11-17)

继续上一篇... (二).构造/析构/赋值运算 ____________________________________________________________________________________________________________________________________ 条款11:在operator= 中处理 "自我赋值" #1.确保当对象自我赋值时 operator=有良好行为.其中包括"自我赋值安全性"和 "异

effective c++条款13-17 “以对象管理资源”之RAII浅析

RAII是指C++语言中的一个惯用法(idiom),它是"Resource Acquisition Is Initialization"的首字母缩写.中文可将其翻译为"资源获取就是初始化".虽然从某种程度上说这个名称并没有体现出该惯性法的本质精神,但是作为标准C++资源管理的关键技术,RAII早已在C++社群中深入人心. 使用局部对象管理资源的技术通常称为"资源获取就是初始化".这种通用技术依赖于构造函数和析构函数的性质以及它们与异常处理的交互作

Effective C++读书笔记(条款18-23)

(四).设计与声明 ____________________________________________________________________________________________________________________________________ 条款18:让接口容易被使用,而不容易被误用 #1.导入新类型可以让接口不易被误用,以函数替换对象则可以保证类型安全性. 例如: class Date{ public: Date(int month, int day

effective C++ 读书笔记 条款17 以独立语句讲newed对象置入智能指针

// Test.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include <memory> //注意加这个头文件 using namespace std; class Widdget { }; int priority() { return 0; } /* 下面的函数可能造成内存泄露: 调用的时候如下: processWiddget(std::tr1::shared_ptr&

Effective C++读书笔记(条款24-29)

Effective C++第四篇,扩展的有点多... (四).设计与声明 ____________________________________________________________________________________________________________________________________ 条款24:若所有参数皆需类型转换,请为此采用non-member函数 #1.如果你需要为某个函数的所有参数(包括被 this指针所指的那个隐喻参数)进行 类型转

Effective C++读书笔记(条款1-10)

不得不说,Effective C++确实是一本C++进阶的好书,刚浏览完第二遍, 现对其做一个大体性的总结 ,并进行适当的展开,作为以后C++参考复习之用. (一).让自己习惯C++ ____________________________________________________________________________________________________________________________________ 条款1:视C++为一个语言联邦 #1.将C++ 分