智能指针其实也不是完全的指针,应该说是像指针一样的类对象,智能指针通常有指针的功能,当然同时也包含了一些额外的功能。目前比较常见的智能指针有auto_ptr、unique_ptr和shared_ptr三种(其实还有weak_ptr第四种),本篇主要也是讲这三种。

auto_ptr是C++98提出来的,到了C++11基本已经摒弃这种用法,但是一些编译器还没有支持C++11的标准,还用C++98的标准,故而auto_ptr可能还在使用。之所以要用到智能指针是因为在一些情况下,开发者可能声明了一个指针并开辟了内存,但是却忘了释放内存,或者有些情况不是忘了释放内存,而是软件出现异常,释放内存的语句没有被执行到,这些原因都容易造成内存泄漏,这也是智能指针出现的一个原因吧。

1、智能指针的使用

C++的智能指针包含在头文件<memory>中,该头文件中定义了智能指针的函数模板,并且在命名空间std中。在声明一个智能指针的时候要声明数据类型,同时传入开辟的堆内存,这里要强调堆内存,不能是栈内存:

auto_ptr<double> apd(new double);    // OK
unique_ptr<double> upd(new double);  // OK
shared_ptr<double> spd(new double);  // OK
    
int dNUM = 1;
auto_ptr<double> apd(dNUM);          // Error

声明了智能指针后就不需要使用delete语句来释放内存了。

所有的智能指针都有一个explicit构造函数,该函数将指针作为参数,因此不需要自动将指针转换为智能指针对象:

shared_ptr<double> spd;
double *pD = new double;
spd = pD;                        //Error
spd = shared_ptr<double>(pD);    //OK
shared_ptr<double> spd1 = pD;    //Error
shared_ptr<double> spd1(pD);     //OK

智能指针的很多用法都跟普通指针一样,可以对它进行接触引用操作(*)、用->或者.访问成员,还可以将智能指针对象赋值给另一个同类型的对象,但是由于智能指针对象有自动回收内存功能,所以这样做容易导致同一块内存被释放两次的问题。

2、有关智能指针的三个方式

为了避免同块内存被释放两次的惨剧,可以有以下三种方式:

1、定义对象赋值运算符,使之执行深拷贝,这样两个智能指针指向不同的内存;

2、建立所有权(ownership)概念,对于特定对象,只能有一个指针拥有它,也只有拥有它的指针可以删除它,然后,让赋值操作转让所有权,这种方法是auto_ptr和unique_ptr使用的策略,unique_ptr会比auto_ptr严格;

3、使用引用计数(reference counting)创建更智能的指针,跟踪引用特定对象的智能指针的数量,赋值时计数加一,指针过期时计数减一,仅当计数为0的时候才调用delete语句释放内存,这就是shared_ptr使用的策略。

3、为何unique_ptr优于auto_ptr

1、unique_ptr赋值给同类型的unique_ptr操作的时候,编译会报错,而auto_ptr会等到运行时才报错;将unique_ptr赋值给另一个的时候,如果该unique_ptr是个临时的右值,也就是赋值后该unique_ptr不会被使用到,如在函数中返回unique_ptr,那么编译器是一般会通过的

2、unique_ptr使用new和delete、new[]和delete[]两种配套,但是auto_ptr只使用new和delete,所以unique_ptr可以用于数组的变体,但是auto_ptr不能。

4、选择

1、如果程序中会用到多个智能指针指向同一对象,那么肯定要用shared_ptr,包括:有一个指针数组,并使用了一些辅助指针来标识特定元素,如最大最小值等;两个第项都包含第三个对象的指针;STL容器包含指针;

2、不会用多个指针指向同一对象,则用unique_ptr,可将unique_ptr转换为shared_ptr;

3、不支持新标准(如C++11以上的)的编译器,只能用auto_ptr;

溪水急著要流向海洋

浪潮却渴望重回土地

在绿树白花的篱前

曾那样轻易地挥手道别

而沧桑了二十年後

我们的魂魄却夜夜归来

微风拂过时

便化作满园的郁香

C++基础--智能指针的更多相关文章

  1. C++ 基础知识回顾(string基础、智能指针、迭代器、容器类)

    [1] string基础 [1.1] string 的构造 #include <iostream> #include <string> int main() { using n ...

  2. [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针]

    [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针] 实用知识 智能指针 我们今天来讲讲Rust中的智能指针. 什么是指针? 在Rust,指针(普通指针),就是保存内存地址的值 ...

  3. c++基础 使用智能指针

    三个智能指针模板(auto_ptr.unique_ptr和shard_ptr)都定义了类似指针的对象(c++11已将auto_ptr摒弃),可以将new获得(直接或间接) 的地址赋给这种对象.当智能指 ...

  4. Boost智能指针-基础知识

    简单介绍 内存管理一直是 C++ 一个比較繁琐的问题,而智能指针却能够非常好的解决问题,在初始化时就已经预定了删除.排解了后顾之忧.1998年修订的第一版C++标准仅仅提供了一种智能指针:std::a ...

  5. ndk学习之c++语言基础复习----C++线程与智能指针

    线程 线程,有时被称为轻量进程,是程序执行的最小单元. C++11线程: 我们知道平常谈C++线程相关的东东基本都是基于之后要学习的posix相关的,其实在C++11有自己新式创建线程的方法,所以先来 ...

  6. C++ 中的智能指针-基础

    简介 在现代 C++ 编程中,标准库包含了智能指针(Smart pointers). 智能指针用来确保程序不会出现内存和资源的泄漏,并且是"异常安全"(exception-safe ...

  7. 【UE4 C++ 基础知识】<15> 智能指针 TSharedPtr、UniquePtr、TWeakPtr、TSharedRef

    基本概念 UE4 对 UObject 对象提供垃圾回收 UE4 对原生对象不提供垃圾回收,需要手动进行清理 方式 malloc / free new / delete new与malloc的区别在于, ...

  8. C++智能指针

    引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...

  9. C++ 引用计数技术及智能指针的简单实现

    一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...

随机推荐

  1. 导弹拦截p1020(LIS问题)

    题目描述(题目链接:https://www.luogu.org/problem/P1020) 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够 ...

  2. SQL Server DATEADD() 函数 一步步使用教程

    SQL Server DATEADD() 函数 DATEADD() 函数在日期中添加或减去指定的时间间隔. DATEADD(datepart,number,date)date 参数是合法的日期表达式. ...

  3. 前端学习笔记系列一:3 Vue中的nextTick

    一.示例 先来一个示例了解下关于Vue中的DOM更新以及nextTick的作用. 模板 <div class="app"> <div ref="msgD ...

  4. zabbix4.4安装 centos7+mysql+Nginx

    1.安装数据源 # rpm -Uvh https://repo.zabbix.com/zabbix/4.4/rhel/7/x86_64/zabbix-release-4.4-1.el7.noarch. ...

  5. CPU、内存、硬盘之间的关系

    要完完全全地讲清楚cpu.内存.硬盘之间的关系,博客的篇幅是不够的.这里简单的介绍以下它们之间的关系,抛砖引玉. 1.CPU即中央处理器,是英语“Central Processing Unit”的缩写 ...

  6. 吴裕雄--天生自然JAVA数据库编程:使用元数据分析数据库

    import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import j ...

  7. 吴裕雄--天生自然JAVA数据库编程:事务处理

    DROP TABLE user ; -- 删除表 CREATE TABLE user( id INT AUTO_INCREMENT PRIMARY KEY , name VARCHAR(30) NOT ...

  8. Deepctr框架代码阅读

    DeepCtr是一个简易的CTR模型框架,集成了深度学习流行的所有模型,适合学推荐系统模型的人参考. 我在参加比赛中用到了这个框架,但是效果一般,为了搞清楚原因从算法和框架两方面入手.在读代码的过程中 ...

  9. iplimage 转HBITMAP

    HBITMAP IplImage2hBitmap(IplImage* pImg) { cvFlip(pImg, NULL); BYTE tmp[]; BITMAPINFO *bmi = (BITMAP ...

  10. 微信小程序自定义组件-下拉框

    这个是网址https://www.cnblogs.com/zjjDaily/p/9548433.html 微信小程序之自定义select下拉选项框组件 知识点:组件,animation,获取当前点击元 ...