C++的智能指针学习笔记(初)
C++ primer plus 16.2节介绍了auto_ptr,该模板类在C++11中已弃用,目前已被shared_ptr代替。
auto_ptr又叫做智能指针,用于管理动态内存分配的用法。
为什么要有auto_ptr?
首先看一个例子,
void remodel(string &str){
string *ps = new string(str);
...
str = ps;
return;
}
此例子有什么缺陷呢?
函数结束的时候没有释放内存,这导致了内存的泄露,指针ps会被释放,但是其指向的内存并没有被释放。一般来说,解决new导致的内存泄露的方法是在return之前使用delete.
但凡是涉及到“别忘了”的操作,都不是最佳的操作,因为一定会有开发者忘记,或者在不经意间删除或者注释掉了这些代码。
就算是没有忘记,也会因为一些别的操作导致内存无法释放,例如以下的代码:
void remodel(string &str)
{
string *ps = new string(str);
...
if(xxx){
throw exception();
}
str = *ps;
delete ps;
return;
}
在delete执行之前,如果执行过程中产生了异常并抛出,则后续的指令都不会执行,这仍将导致内存泄露。
如何解决
首先,我们知道,C++创建一个对象有两种方式,new和直接声明。new一个对象将在堆中动态分配内存来创建一个对象,而直接声明将会在栈内存中创建对象。
(所谓的堆,是指程序内部除了栈和静态存储区之外的"自由空间(free store)",堆内存用于在程序运行时分配对象。)
前者的生命周期是全局的,后者则受到作用域限制,也就是说对于前者产生的对象,如果不去主动释放它,则该对象所占据的内存会一直存在,如果没有指针可以指向它,则会导致内存泄露。
而直接声明的对象,在一个类对象过期的时候,析构函数会在一个对象过期的时候自动执行从而将该对象释放。
不妨这样思考,如果指针能被封装为一个对象,则这个包含指针的对象过期的时候调用其析构函数,将该指针指向的对象delete,不就能够把它指向的内存也释放了吗?
于是auto_ptr便诞生了,auto_ptr是一个模板类,这样便可以创建指向任何类型的智能指针。
auto_ptr的设计和使用
template<class T>class auto_ptr{
public:
explicit auto_ptr(T* p = 0) throw();
};
throw()意味着构造函数不引发异常,因此请求T类型的auto_ptr将获得一个指向T类型的auto_ptr.
这样便定义好了一个智能指针,其实非常简单,就是在构造的时候将普通的指针放入了auto_ptr模板类中
使用的时候
auto_ptr<double> ap(new double);//在构造函数中填入new出来的对象
*ap = 23.3;//ap对象的地址其实就是new出来的double对象的地址,所以可以用指针取值的方式赋值。
所以,改造文章开头的remodel函数:
void remodel(string &str){
auto_ptr<string> ps(new string(str));
...
if(xxx) throw exception();
str=*ps;
return;
}
这里,便不再需要使用delete了。
shared_ptr和unique_ptr
C++11摒弃了auto_ptr,主要是由于auto_ptr无法进行指针的传递。auto_ptr必须显式地初始化,即auto_ptr<string> ps(new string("sdf")),
为了多个指针指向一个new出的对象,C++11提出了shared_ptr,
shared_ptr中增加了引用计数,有N个指向一个同一个内存区域的shared_ptr时,它们共同维护一个引用计数器。
shared_ptr的大概实现如下:
template<typename T> class shared_ptr{
private:
T* _ptr;//指向的对象
int *_count;//引用计数器
public:
...
shared_ptr():_ptr((T*)0),_count(0){}
~shared_ptr(){
if(_ptr && --*count==0){
delete _ptr;
delete _count;
}
}
};
当智能指针的析构函数启用时,只有引用计数为0的时候,才会进行析构。
C++的智能指针学习笔记(初)的更多相关文章
- C++中的智能指针、轻量级指针、强弱指针学习笔记
一.智能指针学习总结 1.一个非const引用无法指向一个临时变量,但是const引用是可以的! 2.C++中的delete和C中的free()类似,delete NULL不会报"doubl ...
- Qt 智能指针学习(7种指针)
Qt 智能指针学习 转载自:http://blog.csdn.net/dbzhang800/article/details/6403285 从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ ...
- Android 智能指针学习 一
Android5.1 中智能指针涉及的文件如下: system/core/include/utils/RefBase.h system/core/libutils/RefBase.cpp system ...
- C++11智能指针读书笔记;
智能指针是一个类对象,而非一个指针对象. 原始指针:通过new建立的*指针 智能指针:通过智能指针关键字(unique_ptr, shared_ptr ,weak_ptr)建立的指针 它的一种通用实现 ...
- Qt 智能指针学习(7种QT的特有指针)
从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int arg ...
- Qt 智能指针学习(7种QT智能指针和4种std智能指针)
从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int arg ...
- Qt 智能指针学习
原地址:http://blog.csdn.net/dbzhang800/article/details/6403285 从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include & ...
- [转]Qt 智能指针学习
从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int arg ...
- c++——智能指针学习(shared_ptr和weak_ptr)
先看一个例子:Stark和Targaryen家族你中有我,我中有你.我们设计以下类企图避免内存泄漏,使得析构函数都能调用到: #include<iostream> #include< ...
随机推荐
- VMware ESXi 7.0 U2 SLIC & Unlocker USB 网卡驱动集成镜像 202109更新
2021.08.31 更新:集成 "vmkusb-nic-fling"."net-community" 和 "nvme-community" ...
- nginx 开启,关闭,重启
2021-08-191. 启动 # 判断配置文件是否正确 cd /usr/local/nginx/sbin ./nginx -t # 启动 cd usr/local/nginx/sbin ./ngin ...
- docker一分钟搭建nginx服务器
运行nginx服务 拉取: docker pull nginx:1.17.9 运行: docker run -d --name nginx -P 80:80 nginx:1.17.9 -d表示在后台启 ...
- Linux从头学12:读完这篇【特权级】文章,你就比别人更“精通”操作系统!
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- 使用Eclipse对weblogic进行远程调试
一.环境说明 weblogic12c,linux centOS 6.5,eclipse mars. 二.步骤 1.找到weblogic根目录下user_projects/domains/域名/bin/ ...
- LVS负载均衡集群--NAT模式部署
目录: 一.企业群集应用概述 二.负载均衡群集架构 三.负载均衡群集工作模式分析 四.关于LVS虚拟服务器 五.NAT模式 LVS负载均衡群集部署 一.企业群集应用概述 1.群集的含义 Cluster ...
- HDU - 3790 最短路径问题 (dijkstra算法)
HDU - 3790 最短路径问题 Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费 ...
- js 获取转换网址中文参数
var search = decodeURI(location.search).substr(1); console.log(search); decodeURI 方法返回一个已编码的统一资源标识符 ...
- ssh 执行 shell脚本执行jps时:-bash: jps: command not found
转至: https://www.codeleading.com/article/67592908468/ 我构建了hadoop集群.我们一定会写一个shell脚本去每一个节点上去jps,查看每个节点的 ...
- mysql给数据库表里某个字段赋随机值
UPDATE sxz_goods set sales_volume_base = round(rand() * 50) + 1 where sales_volume_base =0 ORDER BY ...