【C++ 语言】智能指针 引入 ( 内存泄漏 | 智能指针简介 | 简单示例 )
文章目录
- I . 智能指针 引入
- II . 智能指针 简介
- III . 智能指针 简单示例
I . 智能指针 引入
1 . 示例前提 : 定义一个 Student 类 , 之后将该类对象作为智能指针指向的对象 ;
class Student {public://构造函数Student(){cout << "Student 对象创建" << endl;}//析构函数~Student(){cout << "Student 对象释放" << endl;}};
2 . 栈内存创建对象 : 如果在栈内存中创建对象 , 在方法结束后 , 会自动释放 Student 对象 ;
//栈内存中创建对象 , 在方法结束后 , 会自动释放 Student 对象
void createInStack() {Student student;}
3 . 堆内存创建对象 : 使用 new 在堆内存中创建对象时 , 在 该对象的 作用域 结束后 , 不会自动释放 Student 对象 ;
① 错误示例 : 如下方法中 , 只创建了对象 , 在作用域结束时 , 没有释放该对象 , 这样造成了内存泄漏 ;
//堆内存中创建对象 , 在方法结束后 , 不会自动释放 Student 对象
void createInHeap() {Student *student = new Student;}
② 正确示例 : 使用 new 关键字在堆内存中创建了对象 , 必须在作用域结束前, 将该对象使用 delete 方法释放掉 , 否则会造成内存泄漏 ;
//堆内存中创建对象 , 在方法结束后 , 手动调用 delete 释放 Student 对象
void createInHeapAndDelete() {//在堆内存中创建对象Student* student = new Student;//手动释放 堆内存中创建的对象delete(student);
}
4 . 堆内存创建对象 使用智能指针指向该对象 : 堆内存中创建对象 , 将对象指针设置成智能指针 , 该对象在方法结束时会自动释放 ;
//堆内存中创建对象 , 将对象指针设置成智能指针 , 该对象在方法结束时会自动释放
void createInHeapWithSmartPointer() {Student* student = new Student;shared_ptr<Student> shared_student(student);}
II . 智能指针 简介
C ++ 的 STL ( Standard Template Library 标准模板库 ) 提供了 四种智能指针 :
① shared_ptr : 指向的对象所有权 共享 , 多个指针指向同一个对象 ; 当最后一个智能指针销毁时 , 对象销毁 ;
② weak_ptr : 为了弥补 shared_ptr 的缺陷而引入的智能指针 ;
③ unique_ptr : 指向的对象所有权 互斥 , 同一时间 , 一个 对象 只能有一个 unique_ptr 智能指针 指向它 ;
④ auto_ptr ( 已弃用 ) : 该智能指针在 C++ 11 标准中 已弃用 , 但是为了向低版本兼容 , 目前仍可以使用 ;
写新代码就不要使用 auto_ptr 类型的智能指针了 , 推荐使用 unique_ptr 智能指针 , 该指针是 auto_ptr 的安全进阶版本 ;
III . 智能指针 简单示例
1 . 示例项目下载地址 :
主要代码及逻辑都在下面的主代码示例中 , 没有下载的必要 ;
2 . 头文件 :
// 007_SmartPointer.h: 标准系统包含文件的包含文件
// 或项目特定的包含文件。#pragma once#include <iostream>// TODO: 在此处引用程序需要的其他标头。
3 . 主代码示例 :
// 007_SmartPointer.cpp: 定义应用程序的入口点。
//#include "007_SmartPointer.h"using namespace std;//智能指针原理 :
// 智能指针本质 : 智能指针也是一个对象
// 智能指针存放 : 该智能指针对象处于 栈内存中
// 智能指针释放 : 函数执行完毕后 , 就会调用智能指针对象的析构方法
// 判定引用计数 : 在智能指针对象析构方法的内部就会判定智能指针 操作对象 的引用计数
// 如果这个 操作对象的 引用计数为 0 , 就会调用 delete 方法释放 操作对象 ; class Student {public://构造函数Student(){cout << "Student 对象创建" << endl;}//析构函数~Student(){cout << "Student 对象释放" << endl;}};//栈内存中创建对象 , 在方法结束后 , 会自动释放 Student 对象
void createInStack() {Student student;}//堆内存中创建对象 , 在方法结束后 , 不会自动释放 Student 对象
void createInHeap() {Student *student = new Student;}//堆内存中创建对象 , 在方法结束后 , 手动调用 delete 释放 Student 对象
void createInHeapAndDelete() {//在堆内存中创建对象Student* student = new Student;//手动释放 堆内存中创建的对象delete(student);
}//堆内存中创建对象 , 将对象指针设置成智能指针 , 该对象在方法结束时会自动释放
void createInHeapWithSmartPointer() {Student* student = new Student;shared_ptr<Student> shared_student(student);}//堆内存中创建对象 , 将对象指针设置成智能指针 , 该对象在方法结束时会自动释放
void createInHeapWithTwoSmartPointer() {Student* student = new Student;//声明了一个智能指针对象 , student 的引用计数变成 1shared_ptr<Student> shared_student1(student);//又声明了第二个智能指针对象 , student 的引用计数 变成 2shared_ptr<Student> shared_student2(student);//上面的两个智能指针对象处于栈中 , 当函数结束时 , 这两个智能指针本身会被释放掉// 释放两个智能指针后 , student 对象的引用计数又变成了 0 // 两个智能指针会被回收 , 回收智能指针时 , 会做判定 , 当 对象的引用计数为 0 时// 自动调用该对象的析构函数 , 释放该对象}int main()
{//C++ 11 STL 提供了两种类型的 智能指针//在方法中 , 有两种创建对象的方式 : ① 直接声明对象 , ② 使用 new 创建对象 ; // 直接声明对象 , 是在栈内存中创建实例 , 方法结束后 , 该实例自动释放 ; // 如果使用 new 创建对象 , 是在堆内存中创建 , 创建后返回一个对象的指针 ; // 堆内存中的对象需要手动释放 , new 申请的对象 , 需要调用 delete 释放 ( delete 会触发虚构函数 ) ; // 如果忘记手动释放使用 new 创建的对象 , 就会导致内存泄漏// 因此引入智能指针 , 可以防止忘记手动释放对象导致内存泄漏//栈内存中创建对象 , 自动释放 Student 对象cout << "栈内存中 创建 Student 对象" << endl;createInStack();//堆内存中创建对象 , 不会自动释放 Student 对象cout << "\n堆内存中 创建 Student 对象 , 不主动释放该对象" << endl;createInHeap();cout << "\n堆内存中 创建 Student 对象 , 主动 调用 delete 方法 释放该对象" << endl;//堆内存中创建对象 , 函数结束前手动调用 delete 方法 , 释放该对象createInHeapAndDelete();cout << "\n堆内存中 创建 Student 对象 , 将其设置成智能指针" << endl;//堆内存中创建对象 , 将对象指针设置成智能指针 , 该对象在方法结束时会自动释放createInHeapWithSmartPointer();//智能指针分类 : // 共享智能指针 : shared_ptr , 该智能指针内部实现了引用计数 , 多个共享智能指针指向同一个对象时// 有 N 个 共享 智能指针同一个对象 , 其引用计数为 Nreturn 0;
}
运行结果 :
栈内存中 创建 Student 对象
Student 对象创建
Student 对象释放堆内存中 创建 Student 对象 , 不主动释放该对象
Student 对象创建堆内存中 创建 Student 对象 , 主动 调用 delete 方法 释放该对象
Student 对象创建
Student 对象释放堆内存中 创建 Student 对象 , 将其设置成智能指针
Student 对象创建
Student 对象释放
【C++ 语言】智能指针 引入 ( 内存泄漏 | 智能指针简介 | 简单示例 )相关推荐
- C语言中的指针和内存泄漏
对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧,但 ...
- 【C 语言】二级指针作为输入 ( 自定义二级指针内存 | 为 二级指针 分配内存 - 存放 一维指针 | 为每个 一级指针 分配内存 | 释放二维指针内存 )
文章目录 一.二级指针 1.为 二维指针 分配内存 2.为每个 一维指针 分配内存 3.释放 二维指针 内存 二.完整代码示例 一.二级指针 声明二级指针 : // 声明二维指针char **p = ...
- C++ 内存泄漏检测工具valgrind简单使用
C++ 内存泄漏检测工具valgrind简单使用 目录 C++ 内存泄漏检测工具valgrind简单使用 valgrind安装 valgrind测试内存泄漏 valgrind安装 通过软件商店下载: ...
- C++ 智能指针 :内存泄漏、 RAII、智能指针、auto_ptr、unique_ptr、shared_ptr、weak_ptr、定制删除器deleter
文章目录 内存泄漏 什么是内存泄漏 内存泄漏的危害: 如何避免内存泄漏 RAII 智能指针 auto_ptr unique_ptr shared_ptr 循环引用问题 weak_ptr 定制删除器 内 ...
- 道高一尺 魔高一丈 内存泄漏智能指针
一.什么是内存泄漏 内存泄漏是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果. 内存泄漏主要分为两类: 1. 堆内存泄漏 堆 ...
- C语言中野指针与内存泄漏
内存泄漏 用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元,不能被任何程序再次使用,直到程序结束.即所谓内存泄漏. 注意:内存泄漏是指堆内存的泄漏. 简单的说就是申请了 ...
- 野指针与内存泄漏那些事
野指针:不是NULL指针,是指向垃圾内存的指针 野指针成因: 1.指针变量没有被初始化:指针变量在创建时同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存. 2.指针p被free或者d ...
- Java中会存在内存泄漏吗,请简单描述。
内存泄漏是指不再被使用的对象或者变量一直被占据在内存中. 理论上来说,Java是有GC垃圾回收机制的,也就是说,不再被使用的对象,会被GC自动回收掉,自动从内存中清除. 但是,即使这样,Java也还是 ...
- java中会存在内存泄漏吗,请简单描述
理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因):然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致 ...
最新文章
- 关于通讯作者、第一作者的那点事,你想知道的全都在这里!
- jquery easyui 动态绑定数据列
- 邮箱的正则表达式验证总结经验
- 泛型的作用是什么?——Java系列学习笔记
- [鸟哥linux视频教程整理]03_01_Linux文件管理类命令详解续3
- 反编译一款APP然后重新打包(Windows环境)
- 在多重Catch的情况下得到异常的完整信息
- 纵有倚天剑还要屠龙刀,实现Power BI报表服务器自定义认证
- matlab怎么求三阶导数,三阶样条插值(一阶导数边界条件) matlab程序
- 【读书笔记】 —— 公平与正义
- Linux命令学习符以及安装程序
- 2020 数据中心机房建设方案
- 微信绑定的卡服务器,微信亲属卡有什么作用 微信亲属卡怎么绑定
- UG NX 12 取消选择对象
- 第7章 文件和数据格式化
- cad延伸快捷键_CAD绘图大师都在用的46组快捷键,高效绘图必备
- 智能指针手表_反对智能手表
- AllenNLP—笔记—json
- 斐波那契数列之不死神兔
- 极光笔记丨百亿级数据的实时存取优化与实践