智能指针分析及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 = ) __STL_NOTHROW : ptr(p), owns(p) {}
auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) {
a.owns = ;
}
template<class T> auto_ptr(const auto_ptr<T>& a) __STL_NOTHROW
: ptr(a.ptr), owns(a.owns) {
a.owns = ;
} auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW {
if (&a != this) {
if (owns)
delete ptr;
owns = a.owns;
ptr = a.ptr;
a.owns = ;
}
}
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 = ;
}
}
~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是否为空指针。
智能指针分析及auto_ptr源码的更多相关文章
- JPEG概述和头分析(C源码)
原创文章,转载请注明:JPEG概述和头分析(C源码) By Lucio.Yang 部分内容来自:w285868925,JPEG压缩标准 1.JPEG概述 JPEG是一个压缩标准,又可分为标准 JPE ...
- Android5.1.1 - APK签名校验分析和修改源码绕过签名校验
Android5.1.1 - APK签名校验分析和修改源码绕过签名校验 作者:寻禹@阿里聚安全 APK签名校验分析 找到PackageParser类,该类在文件“frameworks/base/cor ...
- 百度智能手环方案开源(含源码,原理图,APP,通信协议等)
分享一个百度智能手环开源项目的设计方案资料. 项目简介 百度云智能手环的开源方案是基于Apache2.0开源协议,开源内容包括硬件设计文档,原理图.ROM.通讯协议在内的全套方案,同时开放APP和云服 ...
- 【校招面试 之 C/C++】第25题 C++ 智能指针(一)之 auto_ptr
1.智能指针背后的设计思想 我们先来看一个简单的例子: void remodel(std::string & str) { std::string * ps = new std::string ...
- Cesium专栏-填挖方分析(附源码下载)
Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以 ...
- Proxy Server源码及分析(TCP Proxy源码 Socket实现端口映射)
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u014530704/article/de ...
- NIO 源码分析(05) Channel 源码分析
目录 一.Channel 类图 二.begin 和 close 是什么 2.1 AbstractInterruptibleChannel 中的 begin 和 close 2.2 Selector 中 ...
- NIO 源码分析(02-2) BIO 源码分析 Socket
目录 一.BIO 最简使用姿势 二.connect 方法 2.1 Socket.connect 方法 2.2 AbstractPlainSocketImpl.connect 方法 2.3 DualSt ...
- NIO 源码分析(02-1) BIO 源码分析
目录 一.BIO 最简使用姿势 二.ServerSocket 源码分析 2.1 相关类图 2.2 主要属性 2.3 构造函数 2.4 bind 方法 2.5 accept 方法 2.6 总结 NIO ...
随机推荐
- Java 注解(Annotations) 详解
注解是元数据 注解是一种装饰器.一个标记(maker),应用于Java的各种结构之上,例如类.方法.字段.用来为这些结构绑定元数据.注解不包含任何业务逻辑. 只由运行时框架或编译器根据注解信息去执行具 ...
- PHP mysqli_kill() 函数
定义和用法 mysqli_kill() 函数请求服务器杀死一个由 processid 参数指定的 MySQL 线程. 语法 mysqli_kill(connection,processid); 实 ...
- luogu 1156 垃圾陷阱 动态规划
Code: #include <bits/stdc++.h> #define N 4004 #define setIO(s) freopen(s".in"," ...
- js 获取滚动条的高度
function getScrollTop() { var scroll_top = 0; if (document.documentElement && document.docum ...
- Financial Management(SDUT 1007)
Problem Description Larry graduated this year and finally has a job. He's making a lot of money, but ...
- k8s部署03-----常用运维命令
kubectl常用命令 kubectl get nodes #查看集群中有多少个node kubectl describe node <node_name> #查看某个node的详细信息 ...
- leetcode25 K 个一组翻转链表
这道题关于链表的操作,中间指针操作略复杂. /** * Definition for singly-linked list. * struct ListNode { * int val; * List ...
- selenium 学习中遇到的问题汇总
1.使用document.getByClassName时无click事件,然后就不知道怎么办了,也不太懂前端,与开发大哥确认,div 中class实现展开和收起是通过隐藏和显示这种方式实现的,在编写时 ...
- druid 参数配置详解
druid 参数配置详解 */--> druid 参数配置详解 Table of Contents 1. 初始化连接 2. 参数配置及说明 3. 注意事项 3.1. 底层连接 3.2. 空闲检查 ...
- java高级之多线程
1.1,多线程的作用: *线程是程序执行的一条路径, 一个进程中可以包含多条线程 *多线程并发执行可以提高程序的效率, 可以同时完成多项工作 1.2,多线程的应用场景: * 红蜘蛛同时共享屏幕给多个电 ...