C++基础--智能指针
智能指针其实也不是完全的指针,应该说是像指针一样的类对象,智能指针通常有指针的功能,当然同时也包含了一些额外的功能。目前比较常见的智能指针有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++基础--智能指针的更多相关文章
- C++ 基础知识回顾(string基础、智能指针、迭代器、容器类)
[1] string基础 [1.1] string 的构造 #include <iostream> #include <string> int main() { using n ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针]
[易学易懂系列|rustlang语言|零基础|快速入门|(21)|智能指针] 实用知识 智能指针 我们今天来讲讲Rust中的智能指针. 什么是指针? 在Rust,指针(普通指针),就是保存内存地址的值 ...
- c++基础 使用智能指针
三个智能指针模板(auto_ptr.unique_ptr和shard_ptr)都定义了类似指针的对象(c++11已将auto_ptr摒弃),可以将new获得(直接或间接) 的地址赋给这种对象.当智能指 ...
- Boost智能指针-基础知识
简单介绍 内存管理一直是 C++ 一个比較繁琐的问题,而智能指针却能够非常好的解决问题,在初始化时就已经预定了删除.排解了后顾之忧.1998年修订的第一版C++标准仅仅提供了一种智能指针:std::a ...
- ndk学习之c++语言基础复习----C++线程与智能指针
线程 线程,有时被称为轻量进程,是程序执行的最小单元. C++11线程: 我们知道平常谈C++线程相关的东东基本都是基于之后要学习的posix相关的,其实在C++11有自己新式创建线程的方法,所以先来 ...
- C++ 中的智能指针-基础
简介 在现代 C++ 编程中,标准库包含了智能指针(Smart pointers). 智能指针用来确保程序不会出现内存和资源的泄漏,并且是"异常安全"(exception-safe ...
- 【UE4 C++ 基础知识】<15> 智能指针 TSharedPtr、UniquePtr、TWeakPtr、TSharedRef
基本概念 UE4 对 UObject 对象提供垃圾回收 UE4 对原生对象不提供垃圾回收,需要手动进行清理 方式 malloc / free new / delete new与malloc的区别在于, ...
- C++智能指针
引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...
- C++ 引用计数技术及智能指针的简单实现
一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...
随机推荐
- 引用类型--Object类型、Array类型
引用类型的值(对象)是引用类型的一个实例.在ECMAScript中,引用类型是一种数据结构,它描述的是一类对象具有的属性和方法. 对象是某个特定引用类型的实例,新对象是使用new操作符后跟一个构造函数 ...
- [SUCTF 2019]CheckIn
进入靶场只有一个文件上传界面,上传php一句话木马提示非法后缀. 尝试利用php后缀的多样性绕过,发现都被过滤掉了,先把php改成.jpg的图片,提示说有问号在内容中. php后缀的多样性:php语言 ...
- SQL Server DATEADD() 函数 一步步使用教程
SQL Server DATEADD() 函数 DATEADD() 函数在日期中添加或减去指定的时间间隔. DATEADD(datepart,number,date)date 参数是合法的日期表达式. ...
- python 阶乘函数
def num(n): if n == 1: return n return n*num(n-1) print(num(10)) 输出 3628800 该函数使用了递归函数的规则.return 后面为 ...
- c/c++ 获取BMP文件信息
#include <stdio.h> #include <string.h> typedef struct BITMAPFILEHEADER { // BMP文件头 u_int ...
- Python测试进阶——(1)安装Python测试相关模块
安装python 安装pip yum -y install epel-release yum -y install python-pip 安装psutil 参考:https://www.cnblogs ...
- JS+ES6 - 向数组的开头添加一个或更多元素
- wx地址和腾讯地图
如果只是要获取当前用户的经纬度和打开微信自带的地图 只需要 jsApiList: ["getLocation","openLocation"] // 先获得 w ...
- AndroidStudio3.0打开Android Device Monitor
相信很多更新了AndroidStudio3.0的小伙伴会发现无法在工具栏的的Tools->Android->device monitor,打开DeviceMonitor. 今天偶然看到 G ...
- 040、Java中逻辑运算之短路与运算“&&”
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...