浅谈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 在原文的基础上增加自己的想法作为修改 很多初学者弄不清指针和数组到底有什么样的关系.我现在就告诉你: ...
随机推荐
- 实验1 C语言开发环境使用和数据类型,运算符,表达式
part :验证性内容 .输出学号. #include<stdio.h> int main(void){ printf("); ; } .输入两个整数,求它们的乘积. #incl ...
- springboot整合JPA(简单整理,待续---)
整合步骤 引入依赖: <dependencies> <dependency> <groupId>org.springframework.boot</group ...
- 安装mysql5.6
1.创建一个不能登录的的用户: 2.下载一个数据库包: wget 下载网址 3.安装相关依赖包: yum -y install make gcc-c++ cmake bison-devel ncurs ...
- js filter 数组去重
let arr = [1, 2, 3, 10, 4, 5, 1, 3, 5]; let stateNumArr = arr.filter((item, index, array) => { re ...
- fpc软排线焊接
事情是这样的,早前买的5寸树莓派的屏,基本没咋用过,前两天掏出来点亮了发现屏幕有条虚线. 然后我就寻思是不是排线松了,结果手贱,拔的时候把排线撕断了一截,fpc40pin,我撕断了11pin. 因为以 ...
- 利用Java手写简单的httpserver
前言: 在看完尚学堂JAVA300中讲解如何实现一个最简单的httpserver部分的视频之后, 一.前置知识 1.HTTP协议 当前互联网网页访问主要采用了B/S的模式,既一个浏览器,一个服务器,浏 ...
- Django中的FBV与CBV
一. FBV FBV(function based views) 基于函数的视图, 即一个url对应一个视图函数. 1.1 FBV代码示例 urls.py from django.contrib im ...
- Gradle 简记
不是 Gradle,就是 Maven吧.对比下: Maven: 推荐(?)了一个默认的项目结构和生命周期,但是太过死板 虽然暴露了 API 接口,但是插件定制太过复杂 和 Ant 一样,仍然无法表达复 ...
- CocosCreator 小知识
最近在自学creator,有些小坑和解决方案,想记录下来: 1. 防止点击穿透 场景:在游戏界面有功能按钮,上层弹出layer之后,加入了遮罩,但是游戏界面的功能按钮还可以点击,穿透了! 方案1:遮罩 ...
- Vue小项目二手书商城:(二)axios前后端数据交互
实现内容: 写路由接口(express) axios取数据 一.写接口 1.我们要在前端取到后端的数据(之前写的data.json)可以用vue-resourse或者用axios,在vue2之后官方就 ...