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

前言

  在前面的文章中,细致地分析了构造函数,拷贝构造函数,赋值运算符,析构函数这几个类中最重要函数的用法。

  如果严格地遵循这些做法,可以消除绝大部分资源管理的问题。

  然而,要想更灵活的使用对象中的资源,仅仅这些还不够。譬如,若你想自己控制对象资源的生命周期(不要在作用域结束的时候自动被析构掉),那就应当好好考虑下智能指针了。

  有人说,智能指针是属于设计模式范畴的产物,这么说有点偏激,但也确实有点道理。

问题分析

  我们假定有一个投资类Investment:

1 class Investment
2 {
3     // ......
4 };

  很多其他的投资类型都由这个类派生出来,比如股票投资,基金投资等等。

  进一步假设,有某个工厂函数专门供应特定的Investment对象:

1 Investment * createInvestment();

  必须说明的是,这个函数是通过new来在堆中创建对象的,因此,函数结束后,资源并不会释放掉,而是需要调用这个函数的用户来手工释放掉,如下所示:

1 void f()
2 {
3     // ......
4     Investment * pInv = createInvestment();
5     // ......
6     delete pInv;
7     // ......
8 }

  下面问题来了:如果在 4 - 6行之间有 continue 或者 goto 或者其他中断程序执行的语句,那么将会导致 delete 无法运行,从而内存泄露。

  这种情况下,用户肯定是想 pInv 在作用域结束的时候就会自动地释放掉,好在智能指针能解决这个问题。

智能指针介绍

  智能指针的本质其实是一个能够帮用户管理资源的类指针对象。

  许多资源被动态分配于heap后被用于单一区块或函数内,智能指针可以让资源在离开控制流的时候得到释放。

  应用得比较多的有auto_ptr和shared_ptr两种智能指针。

  前者管理的资源必须是一个智能指针所指向的。当前者进行赋值的时候,会将赋值运算符右值的智能指针变成NULL,而其左值获得右边指针原来指向的资源。

  后者管理的资源则未必,它允许多个智能指针指向同一份资源,同时会统计资源被指的个数,只有指向该资源的智能指针都离开了作用域,才会正式析构掉资源。

  智能指针的使用:

1 void f()
2 {
3     // ......
4     std::auto_ptr<Investment>pInv(createInvestment());
5     std::shared_ptr<Investment>pInv(createInvestment());
6     // ......
7 }

  在构造好了智能指针之后,便可以不用理会该资源回收的事,智能指针将会帮你打理!

小结

  1. 当你需要提前实现多态的话,请new一个子类并将结果返回给一个父类指针。

  2. 智能指针不支持内置类型,那是因为C++认为Vector可以完全取代动态分配而得到的数组。

时间: 2024-08-02 20:55:43

使用智能指针管理对象资源的相关文章

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

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

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

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

智能指针学习笔记

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

智能指针auto_ptr源码剖析

何时我们需要智能指针? 资源所有权的共享 共享所有权是指两个或多个对象需要同时使用第三个对象的情况.这第三个对象应该如何(或者说何时)被释放?为了确保释放的时机是正确的,每个使用这个共享资源的对象必须互相知道对方,才能准确掌握资源的释放时间.从设计或维护的观点来看,这种耦合是不可行的.更好的方法是让这些资源所有者将资源的生存期管理责任委派给一个智能指针.当没有共享者存在时,智能指针就可以安全地释放这个资源了. 要编写异常安全的代码时 异常安全简单地说就是在异常抛出时没有资源泄漏并保证程序状态的一

Item 17:在单独的语句中将new的对象放入智能指针 Effective C++笔记

Item 17: Store newed objects in smart pointers in standalone statements. 在单独的语句中将new的对象放入智能指针,这是为了由于其他表达式抛出异常而导致的资源泄漏. 因为C++不同于其他语言,函数参数的计算顺序很大程度上决定于编译器. 如果你在做Windows程序设计,或者DLL开发,可能会经常碰到类似__cdecl,__stdcall等关键字.它们便是来指定参数入栈顺序的. 关于函数和参数的讨论可以参考:C++手稿:函数与

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

Item 13: Use objects to manage resources. 熟悉智能指针的人肯定不会对此觉得陌生.利用C++中对象自动析构的特性,自动地释放资源. C++编译器并未提供自动的垃圾回收机制,因此释放资源的责任落在了开发者的头上. 我们被要求总是成对地使用new和delete,例如: Investment *pInv = createInvestment(); ... delete pInv; createInvestment这样的方法属于工厂方法(factory funct

使用智能指针来管理对象 (基于RAII)

////一个简单的防止内存泄露的例子//void test() { //使用RAII的特性管理资源 //当智能指针unique_ptr被销毁时,它指向的对象也将被销毁 //这里test函数返回后 p将自动销毁 //unique_ptr<int[]> p( new int[200] ); //直接生成资源 //test函数返回后 p不能被正常销毁,就会造成资源泄露 //int* p = new int[200]; } int main() { while( 1 ) { test(); Sleep

条款17:以独立的语句将资源置入智能指针。

先可考虑下下面这个语句: 1 int prioriy(); 2 processWidget(shared_ptr<Widget>(new Widget), priority()); 上面这条语句看似比较正常,不会泄露资源,但是实际上并非如此. 调用上面这个语句的时候基本上分成三步: 1. new Widget 2. 根据Widget对象指针来构造shared_ptr 3. 调用priority(); 但是c++与java不一样,不一定保证上述语句三部的执行步骤,所以下面这种情况也是可能的: 1

智能指针简介

智能指针用于解决常规指针所带来的内存泄露.重复释放.野指针等内存问题.智能指针基于这样的事实得以发挥作用:定义在栈中的智能指针,当超出其作用域时,会自动调用它的析构函数,从而可以释放其关联的内存资源. 之前C++标准库中定义的智能指针std::auto_ptr<T>,因其设计存在缺陷,所以已不再推荐使用.C++11引入了新的智能指针:unique_ptr.shared_ptr和weak_ptr. 一:unique_ptr unique_ptr类似于auto_ptr.两个unique_ptr实例