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.智能指针是什么 简单来说,智能指针是一个类,它对普 ...
随机推荐
- n/20 文本框动态监听输入长度
- php 实现店铺装修8
/** * @title 店铺装修--根据分类获取商品列表 * @param source 是 int 来源(1--h5.2--app) * @param type 是 string 店铺类型--首页 ...
- 在Java中,为什么十六进制数0xFF取反之后对应的十进制数是-256呢?
int number = 0xFF: 字面值是指在程序中无需变量保存,可直接表示为一个具体的数字或字符串的值. 0xFF是一个整数字面值,整数字面值的缺省类型是 int. 我们知道在Java中, in ...
- Lesson 2 Spare that spider
How much of each year do spiders killing insects? Why, you may wonder, should spiders be our friends ...
- Lesson 1 Finding fossil man
Why are legends handed down by storytellers useful? We can read of things that happend 5000 years ag ...
- 将OB86的故障信息保存在DB86中去
出现DP站故障的时候,CPU会自动调用OB86 ,OB86 的20B 局部变量里面有丰富的故障信息,生成数据块DB86 在DB86 中生成5个双字元素的数组ARAY 在OB86中调用 "BL ...
- 继OpenJDK 之后,OpenJFX也将迁移到 Git
导读 近日 OpenJFX 项目负责人 Kevin Rushforth 提交了一份将 OpenJFX 迁移到 GitHub 的提案. OpenJFX 是 JavaFX 的开源实现.JavaFX 是一个 ...
- HiBench成长笔记——(9) Centos安装Maven
Maven的下载地址是:http://maven.apache.org/download.cgi 安装Maven非常简单,只需要将下载的压缩文件解压就可以了. cd /home/cf/app wget ...
- 第1节 IMPALA:4、5、linux磁盘的挂载和上传压缩包并解压
第二步:开机之后进行磁盘挂载 分区,格式化,挂载新磁盘 磁盘挂载 df -lh fdisk -l 开始分区 fdisk /dev/sdb 这个命令执行后依次输 n p 1 回车 回车 w ...
- 洛谷P4427 [BJOI2018]求和
\(\Large\textbf{Description: } \large{一颗n个节点的树,m次询问,每次查询点i到点j的路径上所有节点点深度的k次方的和并对998244353取模(1\leq n, ...