智能指针分析及auto_ptr源码

简介

C++没有内存自动回收机制,对堆内存的管理就是简单的new和delete,每次new出来的内存都需要手动delete释放。但由于忘记、流程复杂或者异常退出等,都有可能导致没有执行delete释放内存,造成内存泄漏。

在实际工程中,我们往往希望将精力放在应用层上而不是费劲心思处理语言的细枝末节(内存释放),于是就有了最原始的只能指针auto_ptr。

智能指针原理

智能指针是一种资源管理类,这个类在构造函数中传入一个原始指针,在析构函数中释放传入的指针。智能指针都是栈上的对象,所以当函数(或者程序)结束时,会自动释放。

通过对*和->的重载,使类的对象具有指针的特性。

auto_ptr源码

下面是侯捷《STL源码剖析》使用的sgi-stl-v2.91版的auto_ptr源码实现,这个版本的可读性非常好,可惜该版本还没有出现shared_ptr和unique_ptr指针,而新版的源码这部分的实现可读性不太友好。所以这里只能呈现auto_ptr的源码,有助于理解只能指针的原理。

template<class X>
class auto_ptr {
private:
    X* ptr;
    mutable bool owns;
public:
    typedef X element_type;
    explicit auto_ptr(X* p = 0) __STL_NOTHROW : ptr(p), owns(p) {}
    auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) {
        a.owns = 0;
    }
    template<class T> auto_ptr(const auto_ptr<T>& a) __STL_NOTHROW
        : ptr(a.ptr), owns(a.owns) {
        a.owns = 0;
    }

    auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW {
        if (&a != this) {
            if (owns)
                delete ptr;
            owns = a.owns;
            ptr = a.ptr;
            a.owns = 0;
        }
    }
    template<class T> auto_ptr& operator=(const auto_ptr<T>& a) __STL_NOTHROW {
        if (&a &= this) {
            if (owns)
                delete ptr;
            owns = a.owns;
            ptr = a.ptr;
            a.owns = 0;
        }
    }
    ~auto_ptr() {
        if (owns)
            delete ptr;
    }

    X& operator*() const __STL_NOTHROW { return *ptr; }
    X* operator->() const __STL_NOTHROW { return ptr; }
    X* get() const __STL_NOTHROW { return ptr; }
    X* release() const __STL_NOTHROW { owns = false; return ptr; }
};

注意:虽然本文主要分析auto_ptr的源码,但不要用auto_ptr ! 在c++11已经弃用。

C++11中常用的智能指针

C++中常用的智能指针有,在C++11中的<memory>中有unique_ptr、shared_ptr、weak_ptr

1. unique_ptr:同一时刻只能由唯一的unique_ptr指向给定对象,不支持拷贝和赋值操作。

2. shared_ptr:可以有多个指针指向相同的对象,通过引用计数机制,支持拷贝和赋值操作。每使用一次,内部引用计数器加1,析构一次,引用计数减1,当计数为0时,释放所指的堆空间。

3. weak_ptr:弱引用。引用计数器有一个问题就是相互引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或者使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有的shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放,所以weak_ptr不保证它指向的内存一定有效,在使用之前需要检查weak_ptr是否为空指针。

原文地址:https://www.cnblogs.com/evenleee/p/11606957.html

时间: 2024-10-14 00:38:09

智能指针分析及auto_ptr源码的相关文章

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

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

【E2LSH源码分析】E2LSH源码综述及主要数据结构

上一小节,我们对p稳定分布LSH的基本原理进行了介绍(http://blog.csdn.net/jasonding1354/article/details/38237353),在接下来的博文中,我将以E2LSH开源代码为基础,对E2LSH的源码进行注解学习,从而为掌握LSH的基本原理以及未来对相似性搜索的扩展学习打下基础. 1.代码概况 E2LSH的核心代码可以分为3部分: LocalitySensitiveHashing.cpp--主要包含基于LSH的RNN(R-near neighbor)数

cocos2d-x 源码分析 : control 源码分析 ( 控制类组件 controlButton)

源码版本来自3.1rc 转载请注明 cocos2d-x源码分析总目录 http://blog.csdn.net/u011225840/article/details/31743129 1.继承结构 control的设计整体感觉挺美的,在父类control定义了整个控制事件的基础以及管理,虽然其继承了Layer,但其本身和UI组件的实现并没有关联.在子类(controlButton,controlSwitch,controlStepper等中实现不同的UI组件).下面通过源码来分析control与

cocos2d-x 源码分析 之 CCTableView源码分析(附使用方法讨论)

cocos2d-x源码总目录 http://blog.csdn.net/u011225840/article/details/31743129 源码来自2.x,转载请注明 1.继承结构 首先来看下CCTableView的继承结构 从继承结构上看,CCTableView是一种CCScrollView,所以为了研究CCTableView的源码,清先去了解CCScrollView的源码http://blog.csdn.net/u011225840/article/details/30033501. 其

从架构师的角度分析Android Handler 源码的正确姿势

Handler的原理是什么?能深入分析下 Handler的实现机制吗?面试官问该问题是想问清楚handler的源码,handler机制如何实现,对消息泵Looper理不理解(更多完整项目下载.未完待续.源码.图文知识后续上传github.) 1. Handler 机制简介 定义 一套 Android 消息传递机制 作用 在多线程的应用场景中,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现 工作线程对UI的更新处理,最终实现异步消息的处理 使用Handler的原因:将工作线程需操作

分析开源项目源码,我们该如何入手分析?(授人以渔)

1 前言 本文接上篇文章跟大家聊聊我们为什么要学习源码?学习源码对我们有用吗?,那么本篇文章再继续跟小伙伴们聊聊源码这个话题. 在工作之余开始写SpringBoot源码分析专栏前,跟小伙伴们聊聊"分析开源项目源码,我们该如何入手分析?"这个话题,我们就随便扯皮,反正是跟小伙伴们一起学习交流,没必要太正式. 小伙伴们看完本文后,若有自己的源码阅读心得可以在下面进行评论或私聊我进行分享,让我从小伙伴们身上GET多点源码阅读的一些技巧,嘿嘿. 2 学习开源框架源码到底难不难? 那么,先跟小伙

智能指针auto_ptr源码剖析

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

effective c++条款13-17 “以对象管理资源”之auto_ptr源码分析

auto_ptr是当前C++标准库中提供的一种智能指针,诚然,auto_ptr有这样那样的不如人意,以至于程序员必须像使用"裸"指针那样非常小心的使用它才能保证不出错,以至于它甚至无法适用于同是标准库中的那么多的容器和一些算法,但即使如此,我们仍然不能否认这个小小的auto_ptr所蕴含的价值与理念. 这里用了Nicolai M. Josuttis(<<The C++ standard library>>作者)写的一个auto_ptr的版本,并做了少许格式上的修

VC++源码分析 - 中国象棋源码分析

下载自 http://www.newxing.com/Code/VC/game/1750.html 运行界面如下: 看下类图: 资源: 主对话框: 源码说明: 本人机对弈程序采用了多种搜索算法.以下是本程序主要的类说明: 1.CEveluation类:估值类,对给定的棋盘进行估值. 2.CMoveGenerator类:走法产生器,对给定的棋盘局面搜索出所有可能的走法. 3.CSearchEngine类:搜索引擎基类. 4.CNegaMaxEngine类:负极大值法搜索引擎. 5.CAlphaBe