我们使用智能指针来自动运行管理内存,避免对原始指针的使用不当而造成内存泄漏。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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++的智能指针的更多相关文章

  1. 浅谈C中的指针和数组(一)

    本文转载地址:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242138.html 在原文的基础上加入自己的想法作为修改. 指针是C/C ...

  2. 浅谈c语言的指针

    对于非计算机专业的同学,c语言的指针往往就是老师的一句“指针不考“就带过了.c语言的指针号称是c语言的灵魂,是c语言中最精妙的部分. 指针本质上也是变量,也就是一段内存,只是他的特殊之处是他存储的数据 ...

  3. 浅谈C++的this指针

    之所以写这篇文章,主要是为了回答网友 zhancaihua123同学的下面几个问题: father* p=new son;p->disp(...);father是父类,son是子类.disp是一 ...

  4. 浅谈 “空指针、野指针、void*”

            Author: JW. Zhou Date: 2014/7/2 一.空指针(0/NULL) 返回NULL和返回0是完全等价的,因为NULL和0都表示空指针,换句话说:空指针是什么,就是 ...

  5. 浅谈C中的指针和数组(七)

    现在到揭露数组名本质的时候了,先给出三个结论: (1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组: (2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量: ( ...

  6. 浅谈C中的指针和数组(六)

    数组和指针,原本不想在写了,觉得这部分差不多了,但是自己在写程序的时候还是发现了一个错误.首先说一下我的要求: 给一个函数传递一个二维数组,然后我想在这个函数里面计算这个数组的行数. 写个类似的错误D ...

  7. 浅谈C中的指针和数组(五)

    前面写了一些C指针和数组的一些知识,但是还有一些很重要的知识没有交代,这里做一个补充. 首先看一下,普通变量(指针也是变量)和数组名查看地址的方式是不同的. 查看数组变量的地址,不需要使用 & ...

  8. 浅谈C中的指针和数组(四)

    原文转载地址:http://see.xidian.edu.cn/cpp/html/476.html 在原文的基础上增加自己的思想作为自己的修改 指针数组和数组指针的内存布局 初学者总是分不出指针数组与 ...

  9. 浅谈C中的指针和数组(二)

    原文转载地址:http://see.xidian.edu.cn/cpp/html/475.html 在原文的基础上增加自己的想法作为修改 很多初学者弄不清指针和数组到底有什么样的关系.我现在就告诉你: ...

随机推荐

  1. [转载]Oracle之xml的增删改查操作

    tip: xmltype函数是将clob字段转成xmltype类型的函数,若字段本身为xmltype类型则不需要引用xmltype()函数 同名标签用数组取值的方式获取,但起始值从1开始 一.查询(Q ...

  2. ceph运维常用指令

    一.集群 1.启动一个ceph 进程 启动mon进程 service ceph start  mon.node1 启动msd进程 service ceph start mds.node1 启动osd进 ...

  3. python 科学计算及数据可视化

    第一步:利用python,画散点图. 第二步:需要用到的库有numpy,matplotlib的子库matplotlib.pyplot numpy(Numerical Python extensions ...

  4. 画多边形form并填充背景色(可以实现圆角边框 有锯齿)

    public Form1() { InitializeComponent(); this.BackColor = ColorTranslator.FromHtml("#F7F1F1" ...

  5. xampp——apache服务启动问题(端口占用)

    Apache启动提示 20:39:02 [Apache] Error: Apache shutdown unexpectedly.20:39:02 [Apache] This may be due t ...

  6. 自制操作系统Antz(7)——实现内核 (上)

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...

  7. Excel导出采用mvc的ExcelResult继承遇到的问题Npoi导出

    #region 构建Excel文档 //创建Excel文件的对象 NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSS ...

  8. HTML和CSS怎么用

    首页> 1.HTML和CSS是什么? ·网站和HTML页面 ·简单理解网站 ·一个房子比喻(HTML比喻成房子,CSS为装修) ·页面的整体结构:有树桩标签对嵌套组成 ·页面的组成单元:元素 · ...

  9. Java 基础知识点小结

    小知识点 所有的程序,都要定义在类里面: 异常 定义方法时,使用 throws 可以用来捕获方法体内没有捕获的异常,然后以 SomeException 抛出异常 java是解释型语言.java虚拟机能 ...

  10. Linux 之CentOS7-VSFTP搭建

    环境 1.俩台Linux 虚拟机 Ser 和 Cli 安装 [root@jm ~]# rpm -ivh /mnt/Packages/vsftpd-3.0.2-10.el7.x86_64.rpm   / ...