C++细节学习之智能指针auto_ptr和tr1::shared_ptr

为什么要用智能指针?

我们知道在C++中,资源管理是个头疼的问题。资源管理最常做的就是内存管理。而指针用起来如果忘记归还,就会导致内存泄露

比如:

class Oneclass{};
int func(){
    Oneclass* one=new Oneclass;
    if(!one)return 1;
    delete one;
    return 0;
}

可见,上面代码中,我们可以发现delete并没什么卵用,函数没有执行到delete,而是直接返回了1;最好的办法就是不用指针,使用对象来管理资源,因为对象有析构函数,当函数执行的最后会调用析构函数自动回收资源。

普通指针还可能导致悬垂指针。一个指针复制另一个指针,两个指针所指的是同一个对象,当使用一个指针改变那对象时,另一个指针还傻傻地以为还是原来的对象。

那肿么办呢?难道就不用指针这一神器了吗?

不用怕,还有智能指针这一神器,我们可以自定义一个智能指针,或者使用标准程序库的auto_ptr;如下:

void func(){
    std::auto_ptr<Oneclass> pt(new Oneclass);
}

当控制流离开func()的之前会自动调用auto_ptr的析构函数释放对象资源。

但是最好别用多个auto_ptr指向同一个对象,因为如果一个auto_ptr释放了那个对象,其它auto_ptr还傻傻地以为他们对象还活着。而且auto-ptr使用复制或者赋值时有点特别,完成复制或赋值后它们会变成null;比如

void func(){
    std::auto_ptr<Oneclass> pt1(new Oneclass);
    std::auto_ptr<Oneclass> pt2(pt1);  //pt1变成null
    std::auto_ptr<Oneclass> pt3=pt2;  //pt2变成null
}

如果把指针比作丈夫,对象比作妻子,那auto_ptr就只能是一夫一妻制了;而下面这位就厉害了,tr1::shared_ptr就可以一妻多夫,它有个计数器,计算他的同妻伙伴的个数,当为0时,他们的对象也没有存在的意义了。比如:

void func(){
    std::tr1::shared_ptr<Oneclass> pt1(new Oneclass);
    std::tr1::shared_ptr<Oneclass> pt2(pt1);  //pt1没变化
    std::tr1::shared_ptr<Oneclass> pt3=pt2;  //pt2没变化
}

虽然auto_ptr和tr1::shared_ptr像是指针,但实质却还是对象,如果函数需要调用一个Oneclass指针的话,那就会出问题,幸运的是它们都提供了一个get成员函数,可以返回原始指针。比如:

void ptuse(const Oneclass* one){};
void func(){
    std::tr1::shared_ptr<Oneclass> pt1(new Oneclass);
    std::auto_ptr<Oneclass> pt2(new Oneclass);
    ptuse(pt1.get());
    ptuse(pt2.get());
}
时间: 2024-08-01 03:28:38

C++细节学习之智能指针auto_ptr和tr1::shared_ptr的相关文章

【C++智能指针 auto_ptr】

<More Effective C++>ITEM M9中提到了auto_ptr,说是当异常产生的时候,怎么释放为对象分配的堆内存,避免重复编写内存释放语句. PS:这里书里面提到函数退出问题,函数退出会清理栈内存,不管是怎么正常退出还是异常退出(仅有一种例外就是当你调用 longjmp 时.Longjmp 的这个缺点是 C++率先支持异常处理的主要原因).建立在此基础上我们才把对指针的删除操作封装到一个栈对象里面.这样函数退出(异常或是正常)就会调用对象的析构函数,达到我们自动清理所封装指针指

【STL学习】智能指针之shared_ptr

前面已经学习过auto_ptr,这里补充另外一种智能指针,比auto_ptr要更强力更通用的shared_ptr. shared_ptr 简介及使用选择  几乎所有的程序都需要某种形式的引用计数智能指针,这种指针让我们不再需要为两个对象或更多对象共享的对象的生命周期而编写复杂的逻辑(写起来有点绕口),当被共享的对象引用计数降为0时,被共享对象被自动析构. 引用计数指针分为插入式(instrusive)和非插入式(non-instrusive)两种.前者要求它所管理的类提供明确的函数或数据成员用于

智能指针auto_ptr源码剖析

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

c++ 11学习笔记--智能指针

C++ 98的 std::auto_ptr已经被彻底遗弃了,取而代之的是unique_ptr.shared_ptr与weak_ptr.大部分时候我们自己手动申请内存方式内存都是没有问题的,问题是如果程序很大了之后,一个复杂的对象,多次拷贝的代价非常高,很多地方都会使用到,只存在一份拷贝显然是最好的,这个时候对象生命周期的管理就会很复杂,所以c++引入了智能指针. 任何事物都会有两面性. Shared_ptr 摘录于Effective C++, 3rd Edition, Item 17: 在 st

智能指针auto_ptr详解

概述:C++中有很多种智能指针,auto_ptr就是其中的一种,该智能指针主要是为了解决"因程序异常退出发生的内存泄漏"这类问题的. 我们先来看下面的问题代码 #include<iostream> #include<memory> #include<exception> using namespace std; //一般指针的处理方式 template<typename T> class OldClass { public: OldCla

C++中的智能指针(auto_ptr)

实际上auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是完全完美的. 本文从下面的8个方面来总结auto_ptr使用的大部分内容. 1. auto_ptr是什么? auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个这样拥有者(auto_ptr).当auto_ptr对象生命

C++:浅谈c++资源管理以及对[STL]智能指针auto_ptr源码分析,左值与右值

C++:浅谈c++资源管理以及对[STL]智能指针auto_ptr源码分析 by 小威威 1. 知识引入 在C++编程中,动态分配的内存在使用完毕之后一般都要delete(释放),否则就会造成内存泄漏,导致不必要的后果.虽然大多数初学者都会有这样的意识,但是有些却不以为意.我曾问我的同学关于动态内存的分配与释放,他的回答是:"只要保证new和delete成对出现就行了.如果在构造函数中new(动态分配内存),那么在析构函数中delete(释放)就可以避免内存泄漏了!" 事实果真如此么?

C++智能指针 auto_ptr

C++智能指针 auto_ptr auto_ptr 是一个轻量级的智能指针, 定义于 memory (非memory.h)中, 命名空间为 std. auto_ptr 适合用来管理生命周期比较短或者不会被远距离传递的动态对象, 最好是局限于某个函数内部或者是某个类的内部. 使用方法: std::auto_ptr<int> pt(new int(10)); pt.reset(new int(11)); 成员函数 3个重要的函数: (1) get 获得内部对象的指针, 由于已经重载了()方法, 因

智能指针auto_ptr

前奏: Garbage Collection 技术一直颇受注目,并且在 Java 中已经发展成熟,成为内存管理的一大利器,但它在 C++ 语言中的发展却不顺利,C++ 为了追求运行速度,20 年来态度坚决地将其排除在标准之外. 为了稍许平复因为没有 Garbage Collection 而引发的 C++ 程序员的怨气,C++对 Smart Pointer 技术采取了不同的态度. 首先,了解一下智能指针, 该方法使用一个指针类来代表对资源的管理逻辑,并将指向资源的句柄(指针或引用)通过构造函数传递