浅谈C++的智能指针
我们使用智能指针来自动运行管理内存,避免对原始指针的使用不当而造成内存泄漏。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C++里可能出现的内存问题大致有这么几个方面:
1. 缓冲区溢出。
2. 空悬指针 / 野指针。
3. 重复释放。
4. 内存泄漏。
5. 不配对的new[] / delete。
6. 内存碎片。
通过正确使用智能指针很容易解决前面5个问题:
1. 缓冲区溢出:用std::vector<char> / srd::string 或自己编写Buffer class 来管理缓冲区,自动记住用缓冲区的长度,并通过成员函数而不是裸指针来修改缓冲区。
2. 空悬指针 / 野指针:用shared_ptr / weak_ptr解决。
3. 重复释放:用scoped_ptr,只在对象析构的时候释放一次。 // unique_ptr
4. 内存泄漏:用scoped_ptr, 对象析构的时候自动释放内存。 // unique_ptr
5. 不配对的new[] / delete:把new[] 统统替换为 std::vector。
-------------引用自 陈硕 《Linux多线程服务端编程》
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面介绍了这几个智能指针的使用:
一、通过std::shared_ptr这种智能指针访问的对象采用共享所有权来管理其生存期。即内部采用引用计数方式,只有当应用计数为0时,会释放所指资源。
shared_ptr<string> p = make_shared<string>("apple");
我们尽可能使用std::make_shared而避免使用new 来创建对象。(可参考《Effective Modern C++》条款21.)
二、std::weak_ptr也是一个应用计数型智能指针,但它不增加对象的引用次数,即弱引用。可以说是std::shared_ptr的一种扩充。weak_ptr不控制对象的生命期,但它知道对象是否还活着(调用lock()) 。
shared_ptr<string> p = make_shared<string>("apple");
weak_ptr<string> wp(p);
shared_ptr<string> sp = wp.lock(); // 如果对象还存在,返回一个shared_ptr,其中包含weak_ptr对象保留的信息。若死了,则返回一个空的shared_ptr。
if (sp) {
}
else {
}
三、unique_ptr与shared_ptr不同的是unique_ptr对所管理的资源进行独享,unique_ptr不允许对资源进行拷贝。用来取代std::auto_ptr,可以替换boost库中的scoped_ptr。
unique_ptr<int> p1 = make_unique<int>();
unique_ptr<int> p2(p1); // error
unique_ptr<int> p3 = p1; // error
我们尽可能使用std::make_unique而避免使用new 来创建对象。(可参考《Effective Modern C++》条款21.)
测试代码(以shared_ptr为例智能指针日常使用, 测试环境: VS2017):
#include <iostream>
#include <memory>
#include <string> using namespace std; class apple
{
public:
apple(const string& s = "") : number(s) { }
string getString() const { return number; }
private:
string number;
}; class decorate final
{
public:
decorate() = delete; // 不允许单独创建decorate对象
decorate(const shared_ptr<apple>& rhs) :pta(rhs){ }
decorate(const decorate& rhs) : pta(make_shared<apple>(*rhs.pta)) { }
decorate& operator=(const decorate& rhs); shared_ptr<apple> getPtr() const { return pta; }
private:
shared_ptr<apple> pta;
}; decorate& decorate::operator= (const decorate& rhs)
{
if (this != &rhs)
pta = rhs.pta;
return *this;
} int main()
{
shared_ptr<apple> pta = make_shared<apple>("yantai-apple");
decorate myDec(pta);
cout << myDec.getPtr()->getString() << endl; return ;
}
浅谈C++的智能指针的更多相关文章
- 浅谈C中的指针和数组(一)
本文转载地址:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242138.html 在原文的基础上加入自己的想法作为修改. 指针是C/C ...
- 浅谈c语言的指针
对于非计算机专业的同学,c语言的指针往往就是老师的一句“指针不考“就带过了.c语言的指针号称是c语言的灵魂,是c语言中最精妙的部分. 指针本质上也是变量,也就是一段内存,只是他的特殊之处是他存储的数据 ...
- 浅谈C++的this指针
之所以写这篇文章,主要是为了回答网友 zhancaihua123同学的下面几个问题: father* p=new son;p->disp(...);father是父类,son是子类.disp是一 ...
- 浅谈 “空指针、野指针、void*”
Author: JW. Zhou Date: 2014/7/2 一.空指针(0/NULL) 返回NULL和返回0是完全等价的,因为NULL和0都表示空指针,换句话说:空指针是什么,就是 ...
- 浅谈C中的指针和数组(七)
现在到揭露数组名本质的时候了,先给出三个结论: (1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组: (2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量: ( ...
- 浅谈C中的指针和数组(六)
数组和指针,原本不想在写了,觉得这部分差不多了,但是自己在写程序的时候还是发现了一个错误.首先说一下我的要求: 给一个函数传递一个二维数组,然后我想在这个函数里面计算这个数组的行数. 写个类似的错误D ...
- 浅谈C中的指针和数组(五)
前面写了一些C指针和数组的一些知识,但是还有一些很重要的知识没有交代,这里做一个补充. 首先看一下,普通变量(指针也是变量)和数组名查看地址的方式是不同的. 查看数组变量的地址,不需要使用 & ...
- 浅谈C中的指针和数组(四)
原文转载地址:http://see.xidian.edu.cn/cpp/html/476.html 在原文的基础上增加自己的思想作为自己的修改 指针数组和数组指针的内存布局 初学者总是分不出指针数组与 ...
- 浅谈C中的指针和数组(二)
原文转载地址:http://see.xidian.edu.cn/cpp/html/475.html 在原文的基础上增加自己的想法作为修改 很多初学者弄不清指针和数组到底有什么样的关系.我现在就告诉你: ...
随机推荐
- 火狐开发----从头用到尾的cfx
此教程阐述了如何使用 SDK 开发一个简单的扩展. 准备 要想使用 SDK 开发 Firefox 的扩展,您首先需要 安装并激活 SDK.一旦您完成了以上步骤,您将会看到一个命令行窗口. 初始化一个空 ...
- hadoop(原生及CDH发行版)关键目录、配置文件及服务对应文件名详解
四个最主要的配置文件(原生版本位于$HADOOP_HOME\etc\hadoop目录):mapred-site.xmlcore-site.xmlhdfs-site.xmlyarn-site.xml 在 ...
- 【题解】Luogu P4198 楼房重建
原题传送门 根据斜率来建线段树,线段树维护区间最大斜率以及区间内能看见的楼房的数量(不考虑其他地方的原因,两个节点合并时再考虑) 细节见程序 #include <bits/stdc++.h> ...
- JavaWeb三大组件
一.JavaWeb三大组件 Servlet,Listener,Filter.它们在JavaWeb开发中分别提供不同的功能. JavaWeb三大组件都必须在Web.xml中配置 二.三大组件 1.Ser ...
- Maven打war包命令
https://jingyan.baidu.com/article/295430f1e7c4b30c7e005095.html clean compile package
- Python类元编程初探
在<流畅的Python>一书中提到: Classes are first-class object in Python, so a function can be used to crea ...
- blogger添加代码高亮
blogger(blogspot)自带的是没有代码高亮的,我们可以用下面的方法添加代码高亮. 首先我们打开blogger(blogspot)后台,然后点击主题背景-->修改html,然后在弹出的 ...
- VMware15 安装centos7标准板
VM主页——>创建虚拟机——>典型——>下一步: 选择安装安装操作系统,进入选择客户机操作系统界面 选择Linux 版本centos7 64位: 下一步——>填写虚拟机名称, ...
- 20165306 Exp6 信息搜集与漏洞扫描
Exp6 信息搜集与漏洞扫描 一.实践内容概述 1.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 搜索网址目录结构 搜索特定类型的文件 搜索E-Ma ...
- Jenkins去GitLab拉取Java代码自动打包
jenkins的部署 一.部署git 1)先检查系统是否已经自带了git,如果有,就卸载 $ rpm -qa | grep git && rpm -e git --nodeps 2)开 ...