Item 13:使用对象(智能指针)来管理资源 Effective C++笔记

Item 13: Use objects to manage resources.

熟悉智能指针的人肯定不会对此觉得陌生。利用C++中对象自动析构的特性,自动地释放资源。 C++编译器并未提供自动的垃圾回收机制,因此释放资源的责任落在了开发者的头上。 我们被要求总是成对地使用newdelete,例如:

Investment *pInv = createInvestment();
...
delete pInv;

createInvestment这样的方法属于工厂方法(factory
function),用来创建一个对象的实例。

上述代码确实能够在不泄漏内存的情况下很好地执行,但问题出在createInvestment()函数把释放资源的责任交给了客户,
但并未显式地声明这一点,因而客户有时并不知情。即使客户知道该资源需要销毁, 也可能由于流控制语句或者异常的出现而使得资源未被及时释放。

幸运的是,我们可以用对象来包装资源,并在析构函数中释放它。这样客户便不需要维护资源的内存了。 std::auto_ptr便是这样一个对象,它被称为智能指针(smart
pointer)。 典型的使用场景是,资源在堆空间中存储但只在局部被使用。

void f(){
  std::auto_ptr<Investment> pInv(createInvestment());
}

关于C++中堆空间、栈空间的使用方式,可以参考:进程的地址空间:TEXT,DATA,BSS,HEAP,STACK

f()调用结束时pInv退出作用域,析构函数被调用,最终使得资源被释放。
事实上,让createInvestment直接返回智能指针是更好的设计。
可以看到,使用对象来管理资源的关键在于:创建资源后立即放入资源管理对象中,并利用资源管理对象的析构函数来确保资源被释放。

资源管理对象的实现框架正是RAII原则:acquisition is initialization,用一个资源来初始化一个智能指针。指针的析构函数中释放资源。

值得注意的是,为了防止对象被多次释放,auto_ptr应当是不可复制的。 复制一个auto_ptr会使它变成空,资源被交付给另一个只能指针。

std::auto_ptr<int> p1 (new int);
*p1.get()=10;

std::auto_ptr<int> p2 (p1);

std::cout << "p2 points to " << *p2 << ‘\n‘;
// p2 points to 10
// (p1 is now null-pointer auto_ptr)

.get方法返回资源的指针。

auto_ptr古怪的复制行为导致它并不是管理资源的最佳方式,甚至在STL中auto_ptr的容器也是不允许的:
可以创建这样的容器,但往里面添加元素(例如push_back)时会导致编译错。

auto_ptr<int> p1(new int);

vector<auto_ptr<int>> v;    // OK,可以编译
v.push_back(p1);            // 编译错!

此处我们引入一个引用计数(reference-counting smart pointer,RCSP)的指针shared_ptr
它在没有任何其他指针引用到该资源时,进行资源的释放。不同于垃圾回收器,shared_ptr未能解决环状引用的问题。

值得注意的是auto_ptrshared_ptr只能管理单个资源,因为它们是使用delete而非delete[]来实现资源释放的。常见的错误便是传递数组进去:

std::tr1::shared_ptr<int> spi(new int[1024]);

在最新的C++标准中,智能指针已经归入std命名空间了。我们可以这样使用:std::shared_ptr<int>

虽然智能指针有这样的问题,但C++并未提供管理数组的智能指针,因为vector等容器就可以很好地完成这个工作。
如果你真的需要,可以求助与Boost社区的boost::scoped_arrayboost::shared_array



除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/08/02/effective-cpp-13.html

版权声明:本文为博主原创文章,转载请附上原文链接。

时间: 2024-10-08 06:35:36

Item 13:使用对象(智能指针)来管理资源 Effective C++笔记的相关文章

Effective C++ .13使用智能指针来引用资源

#include <iostream> #include <cstdlib> #include <memory> using namespace std; class Kiwi { private: int weight; public: Kiwi(int w) : weight(w) {} ~Kiwi() { cout<<"~Kiwi"<<endl; } int getWeight() {return weight;} };

Item 39:明智地使用private继承 Effective C++笔记

www.mafengwo.cn/event/event.php?iid=4886087www.mafengwo.cn/event/event.php?iid=4886106www.mafengwo.cn/event/event.php?iid=4886060www.mafengwo.cn/event/event.php?iid=4885815www.mafengwo.cn/event/event.php?iid=4886125www.mafengwo.cn/event/event.php?iid

第十一章:使用智能指针管理对象资源

前言 在前面的文章中,细致地分析了构造函数,拷贝构造函数,赋值运算符,析构函数这几个类中最重要函数的用法. 如果严格地遵循这些做法,可以消除绝大部分资源管理的问题. 然而,要想更灵活的使用对象中的资源,仅仅这些还不够.譬如,若你想自己控制对象资源的生命周期(不要在作用域结束的时候自动被析构掉),那就应当好好考虑下智能指针了. 有人说,智能指针是属于设计模式范畴的产物,这么说有点偏激,但也确实有点道理. 问题分析 我们假定有一个投资类Investment: 1 class Investment 2

使用智能指针管理对象资源

前言 在前面的文章中,细致地分析了构造函数,拷贝构造函数,赋值运算符,析构函数这几个类中最重要函数的用法. 如果严格地遵循这些做法,可以消除绝大部分资源管理的问题. 然而,要想更灵活的使用对象中的资源,仅仅这些还不够.譬如,若你想自己控制对象资源的生命周期(不要在作用域结束的时候自动被析构掉),那就应当好好考虑下智能指针了. 有人说,智能指针是属于设计模式范畴的产物,这么说有点偏激,但也确实有点道理. 问题分析 我们假定有一个投资类Investment: 1 class Investment 2

智能指针学习笔记

1. 介绍 本文介绍智能指针的使用.智能指针是c++ 中管理资源的一种方式,用智能指针管理资源,不必担心资源泄露,将c++ 程序员 从指针和内存管理中解脱出来,再者,这也是c++发展的趋势(这话不是我说的,见<Effective c++>和<c++实践编程>),应该认真学习一下. 智能指针中,最有名的应该数auto_ptr,该智能指针已经被纳入标准库,只需要包含<memory>头文件即可以使用,另外,TR1文档定义的shared_ptr和weak_ptr也已经实现(我用

boost智能指针之shared_ptr和weak_ptr

std::auto_ptr很多的时候并不能满足我们的要求,比如auto_ptr不能用作STL容器的元素.boost的smart_ptr中提供了4种智能指针和2种智能指针数组来作为std::auto_ptr的补充. shared_ptr<boost/shared_ptr.hpp>:使用shared_ptr进行对象的生存期自动管理,使得分享资源所有权变得有效且安全. weak_ptr<boost/weak_ptr.hpp>:weak_ptr 是 shared_ptr 的观察员.它不会干

C++ 智能指针

本文转自: http://blog.csdn.net/xt_xiaotian/article/details/5714477 (纯属自学转载) 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见. 用智能指针便可以有效缓解这类问题,本文主要讲解参见的智能指针的用法.包括:std::auto_ptr.boost::sco

(转)剖析C++标准库智能指针(std::auto_ptr)

不可否认,资源泄露(resource leak)曾经是C++程序的一大噩梦.垃圾回收 机制(Garbage Collection)一时颇受注目.然而垃圾自动回收机制并不能 满足内存管理的即时性和可视性,往往使高傲的程序设计者感到不自在. 况且,C++实现没有引入这种机制.在探索中,C++程序员创造了锋利的 "Smart Pointer".一定程度上,解决了资源泄露问题. 也许,经常的,你会写这样的代码: //x拟为class: // class x{ // public: // int

引用计数的智能指针的实现

引用计数的智能指针是对<Effective C++ 条款13:以对象管理资源>的一个实现. 我们要设计一个智能指针,使他能够管理资源,在正确的实际调用资源的析构函数. 首先我们需要一个指针reference来指向资源,当智能指针构造时,用reference指针指向资源,在我们确定资源应该被析构时,我们对reference指针进行delete. 如果只有reference指针的话,只能实现出auto_ptr的效果,我们还需要添加引用计数系统counter来统计指向资源的智能指针的个数.count