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

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

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. linux 网络设置

    centos7 ifcfg-ens33静态ip地址配置 vim /etc/sysconfig/network-scripts/ifcfg-ens33  TYPE=EthernetPROXY_METHO ...

  2. 安卓recyclerView 分割线的那些事

    在这里我想记录下recyclerView 分割线遇到的一些问题,主要提供一些个人思路,代码可能不多~ 1.宽度问题 描述:我现在需要做一张卡片,卡片里面是一条条联系人,而且我们卡片外层是有阴影的,我的 ...

  3. postman工具的使用

    https://www.cnblogs.com/rookie-c/p/5753948.html#4100341 https://www.jellythink.com/archives/category ...

  4. 初试fiddler

    1.tools->Options->HTTPS勾:Decrypt HTTPS traffic //勾:Ignore server certificate errors(unsafe) // ...

  5. 配置IPV6地址

    题:在考试系统上设定接口eth0使用下列IPV6地址: system1上的地址应该是2003:ac18::305/64 system2上的地址应该是2003:ac18::30a/64 两个系统必须能与 ...

  6. oracle 锁表

    select b.username,b.sid,b.serial#,logon_time from v$locked_object a,v$session b where a.session_id = ...

  7. SharePoint2007使用WebPart加载UserControl

    之前一直做SharePoint2010开发,最近转向了2007开发,感觉两者开发时有很多地方不一样,我现在接触到2007开发项目里面使用Module去加载Application Page,而在Appl ...

  8. vi编辑器使用记录

    01. vi 简介 1.1 学习 vi 的目的 在工作中,要对 服务器 上的文件进行 简单 的修改,可以使用 ssh 远程登录到服务器上,并且使用 vi 进行快速的编辑即可 常见需要修改的文件包括: ...

  9. 意外get接近完美的黑苹果 (UEFI + GPT)

    本人大学生一枚,对于高大上的 MAC OS 只能是摸摸口袋 咽咽口水啦.听说黑苹果,就是安装在普通的 pc 上的 MAC系统,那么对应的苹果电脑上的 MAC OS 系统就为白苹果了. 个人也想啃一口黑 ...

  10. VS 编译错误【error C4996: 'scanf': This function or variable may be unsafe. 】的解决方案

    在VS中编译 C 语言项目,如果使用了 scanf 函数,编译时便会提示如下错误: error C4996: 'scanf': This function or variable may be uns ...