一、概念

堆内存对象需要手动使用delete销毁如果没有使用delete销毁就会造成内存泄漏

所以C++在ISO98标准引入了智能指针概念ISO11趋于完善

使用智能指针可以堆内存对象具有栈内存对象特点原理需要手动回收内内存对象套上一个栈内存的模板类对象即可

使用智能指针需要引入头文件#include<memory>

C++四种智能指针

● auto_ptr自动指针)C++ISO98 ,已废弃)

● unique_ptr唯一指针)C++ISO11)

● shared_ptr共享指针C++ISO11)

● weak_ptr虚指针)C++ISO11)

二、auto_ptr 

#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"构造函数"<<endl;}~Test(){cout<<s<<"析构函数"<<endl;}void show(){cout<<s<<"对象执行"<<endl;}
};
int main()
{{//创建一个Test对象,t1指针指向对象Test *t1=new Test("A");//将对象t1交给ap1管理auto_ptr<Test>ap1(t1);//访问对象的成员函数ap1.get()->show();  //ap1.get() <=等价=> t1//释放智能指针ap1对对象t1的管理权,但不销毁对象
//    ap1.release();//释放智能指针ap1对对象t1的管理权,且销毁对象
//    ap1.reset();//创建新的对象t2,销毁原t1对象,并将ap1管理的对象换为t2Test *t2=new Test("B");ap1.reset(t2);//    //以上两句代码可简写为
//    ap1.reset(new Test("B"));ap1.get()->show();cout<<"局部代码块执行结束"<<endl;}cout<<"程序运行结束"<<endl;return 0;
}/*
A构造函数
A对象执行
B构造函数
A析构函数
B对象执行
局部代码块执行结束
B析构函数
程序运行结束
*/

由于成员变量存在指针类型,其拷贝构造函数和赋值运算符重载函数的使用会出现问题,与浅拷贝不同,auto_ptr的复制语义(拷贝构造函数、赋值运算符重载函数)会导致智能指针对对象控制权的转移(非程序员本意),这也是他被废弃的原因

#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"构造函数"<<endl;}~Test(){cout<<s<<"析构函数"<<endl;}void show(){cout<<s<<"对象执行"<<endl;}
};
int main()
{{//创建一个Test对象,t1指针指向对象Test *t1=new Test("A");//将对象t1交给ap1管理auto_ptr<Test>ap1(t1);cout<<ap1.get()<<endl;//显示调用拷贝构造函数auto_ptr<Test>ap2(ap1);//对t1的管理权从ap1到了ap2cout<<ap1.get()<<" "<<ap2.get()<<endl;//隐式调用拷贝构造函数auto_ptr<Test>ap3=ap2;//对t1的管理权从ap2到了ap3cout<<ap1.get()<<" "<<ap2.get()<<" "<<ap3.get()<<endl;//使用赋值运算符auto_ptr<Test>ap4;ap4=ap3; //对t1的管理权从ap3到了ap4cout<<ap1.get()<<" "<<ap2.get()<<" "<<ap3.get()<<" "<<ap4.get()<<endl;cout<<"局部代码块执行结束"<<endl;}cout<<"程序运行结束"<<endl;return 0;
}/*
A构造函数
0x1162670
0 0x1162670
0 0 0x1162670
0 0 0 0x1162670
局部代码块执行结束
A析构函数
程序运行结束
*/

三、unique_ptr 

作为auto_ptr的改进,unique_ptr对其他持有资源对象具有唯一控制权不可以通过常规复制语法转移或者拷贝资源对象控制

 

 

#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"构造函数"<<endl;}~Test(){cout<<s<<"析构函数"<<endl;}void show(){cout<<s<<"对象执行"<<endl;}
};
int main()
{{//创建一个Test对象,t1指针指向对象Test *t1=new Test("A");//将对象t1交给up1管理unique_ptr<Test>up1(t1);cout<<up1.get()<<endl;//显示调用拷贝构造函数unique_ptr<Test>up2(move(up1));cout<<up1.get()<<" "<<up2.get()<<endl;//隐式调用拷贝构造函数unique_ptr<Test>up3=move(up2);cout<<up1.get()<<" "<<up2.get()<<" "<<up3.get()<<endl;//使用赋值运算符unique_ptr<Test>up4;up4=move(up3);cout<<up1.get()<<" "<<up2.get()<<" "<<up3.get()<<" "<<up4.get()<<endl;cout<<"局部代码块执行结束"<<endl;}cout<<"程序运行结束"<<endl;return 0;
}/*
A构造函数
0xed2670
0 0xed2670
0 0 0xed2670
0 0 0 0xed2670
局部代码块执行结束
A析构函数
程序运行结束
*/

 四、shared_ptr

 

每次多一个shared_ptr对资源进行管理引用计数+1每个指向该对象shared_ptr对象销毁时引用计数-1最后一个shared_ptr对象销毁时计数清零资源对象销毁
(即对于所有管理某对象A的 shared_ptr,这些 shared_ptr共享的资源有:引用计数、对象资源) 
#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"构造函数"<<endl;}~Test(){cout<<s<<"析构函数"<<endl;}void show(){cout<<s<<"对象执行"<<endl;}
};
int main()
{shared_ptr<Test>sp3;{shared_ptr<Test>sp1=make_shared<Test>("A");cout<<"引用计数:"<<sp1.use_count()<<endl;cout<<"-------------"<<endl;shared_ptr<Test>sp2(sp1);cout<<"引用计数:"<<sp2.use_count()<<endl;cout<<"引用计数:"<<sp1.use_count()<<endl;cout<<"-------------"<<endl;sp3=sp2;cout<<"引用计数:"<<sp3.use_count()<<endl;cout<<"局部代码块执行结束"<<endl;}//此时sp1、sp2都已销毁,所以引用计数减2cout<<"引用计数:"<<sp3.use_count()<<endl;cout<<"程序运行结束"<<endl;return 0;
}/*
A构造函数
引用计数:1
-------------
引用计数:2
引用计数:2
-------------
引用计数:3
局部代码块执行结束
引用计数:1
程序运行结束
A析构函数*/

 五、weak_ptr

weak_ptr一个不控制资源对象智能指针不会影响资源引用计数主要目的协助shared_ptr工作

通过weak_ptr构造函数参数传入一个持有资源对象shared_ptr或者weak_ptr对象即可创建weak_ptr与资源对象呈弱相关性,因此不支持get等函数直接操作资源对象.

建议weak_ptr调用lock函数之前,先检测引用计数是否大于0,或使用expired()函数检测是否可转换为shared_ptr.

  • 因为不会增加引用计数,所以作为观察者,观察对象是否被释放
  • 若shared_ptr失效,weak_ptr可以通过lock函数“转正”
  • shared_ptr在特殊场景下也会造成内存泄漏(循环引用导致智能指针内存泄漏的问题),可以使用weak_ptr来解决
#include <iostream>
#include <memory>
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout<<s<<"构造函数"<<endl;}~Test(){cout<<s<<"析构函数"<<endl;}void show(){cout<<s<<"对象执行"<<endl;}
};
int main()
{weak_ptr<Test>wp3;{shared_ptr<Test>sp1=make_shared<Test>("A");weak_ptr<Test>wp1=sp1;weak_ptr<Test>wp2(wp1);cout<<sp1.use_count()<<endl;cout<<wp1.use_count()<<endl;cout<<wp2.use_count()<<endl;cout<<"-----------"<<endl;//weak_ptr可以通过lock函数“转正”shared_ptr<Test>sp2=wp1.lock();wp3=wp2;cout<<wp3.use_count()<<endl;cout<<"局部代码块执行结束"<<endl;}//判断能否转正cout<<wp3.use_count()<<endl;if(wp3.expired()){cout<<"weak_ptr无法转正"<<endl;}cout<<"程序运行结束"<<endl;return 0;
}/*
A构造函数
1
1
1
-----------
2
局部代码块执行结束
A析构函数
0
weak_ptr无法转正
程序运行结束*/

 六、其他

1.nullptr

在C++11使用nullptr代替NULL作为空指针表示方式C++可以用作空指针常量表示指针指向任何有效内存地址

 2.类型推导

2.1  auto

使用auto关键字可以推导类型C++11引入

#include <iostream>
#include <memory>
using namespace std;int main()
{auto i1=10;//typeof(i1)-->整型auto i2=1.5;//typeof(i2)-->浮点型auto i3=new auto(10); //typeof(i3)-->int *//int* i3=new int(10);cout<<*i3<<" "<<i3<<endl;auto i4='a';//typeof(i4)-->charreturn 0;
}

2.2 decltypt

decltypt可以推导表达式类型需要注意decltypt只会分析表达式类型不会具体计算表达式

3.初始化列表

#include <iostream>
#include <array>
#include <vector>using namespace std;class Student
{
private:string name;int age;
public:Student(string name,int age):name(name),age(age){}void show(){cout << name << " " << age << endl;}
};int main()
{Student s = {"张胜男",18}; // 列表初始化s.show();array<int,5>arr1 = {1,3,4,5,6};vector<int> vec1 ={1,2,3};int arr2[] = {2,3,45,6};int a{};cout << a << endl;  // 0return 0;
}

4.面试题

【面试题】C++11学过那些特性
  • auto(类型推导)
  • 智能指针(unique_ptr、 shared_ptr、weak_ptr)
  • 初始化列表
  • for-each
  • 类型转换函数
  • 继承构造
  • array
  • override

 5.  进制输出

C++11可以对整数进行不同进制输出
#include <iostream>using namespace std;int main()
{// 为了区分不同进制,可以增加进制显式的功能,此功能设定持久cout << showbase;cout << dec << 1234 << endl;    // 1234cout << oct << 1234 << endl;    // 02322// 输出进制是持久的cout << 9 << endl;  // 011cout << hex << 256 << endl; // 0x100// 取消进制显式的功能cout << noshowbase;cout << 16 << endl; // 10return 0;
}

6.  设定输出域宽度

可以使用setw()制定一个整数或者一个字符串输出占用与宽度

● 设定宽度小于数据本身时仍然显示为数据本身宽度

● 设定域宽度大于数据本身显式未设定宽度

 

#include <iostream>
#include <iomanip>using namespace std;int main()
{// 仍然会按照实际的宽度输出cout << setw(5) << 123456 << setw(5) << 123456 << endl;cout << setw(10) << 123456 << setw(10) << 123456 << endl;// 域宽度 只能作用于下一行cout << setw(10);cout << 123456 << endl;cout << 123456 << endl;return 0;
}

拓展学习

C++如何实现多线程多进程案例:线程池)

文件处理案例:日志系统)

客户端服务器高并发  

Lambda表达式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88399.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88399.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/88399.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python3虚拟机线程切换过程

python实现了自己的多线程&#xff0c;为了保证线程安全&#xff0c;引入了全局解释器锁GIL&#xff0c;只有拿到GIL的线程才能执行&#xff0c;所以在python中同一时刻只能有一个线程在运行&#xff0c;python多线程无法发挥多核处理器的威力&#xff0c;《python源码剖析》中…

PYTHON从入门到实践5-列表操作

# 【1】列表是可变的&#xff0c;可以修改、追加、删除 import randomclass Friend(object):def __init__(self, name, age):self.name nameself.age ageif __name__ __main__:friendList []for i in range(0, 9):randomNumber random.randint(0, 100)friend Friend(f&qu…

【linux】network服务启动网卡流程

目录 1、介绍2、ifup流程【1】与NetworkManager兼容【2】ifup-eth设置ip【3】ifup-routes设置路由 1、介绍 network服务的核心由/etc/sysconfig/network-scripts/下一堆脚本配置来生效&#xff0c;其中启动网卡就是通过ifup脚本来实现的&#xff0c;下面就讲一下ifup如何恢复i…

如何防止自己的电脑被控制?开启二次验证保护教程

远程操作什么最重要&#xff1f;安全&#xff0c;安全&#xff0c;和安全&#xff01;答案永远是安全&#xff01;那么究竟如何能让远程连接安全性更上一层台阶呐&#xff1f;又是哪家远控安全策略方面最给力呐&#xff1f;这可不是王婆卖瓜&#xff0c;自卖自夸&#xff0c;确…

微信小程序节点相关总结

微信小程序节点事件总结 bindtap、catchtap、bindclick的区别&#xff1f;bindclick 和 bindtap 的区别在于&#xff1a; e.target和e.currentTargete.typee.timeStamp触摸事件属性&#xff08;针对触摸类事件&#xff09;坐标信息事件绑定数据冒泡与捕获相关其他特殊属性**常见…

XSD是什么,与XML关系

XSD&#xff08;XML Schema Definition&#xff09;是用于描述XML文档结构和内容的一种规范。它定义了XML文档中元素、属性、数据类型、数据格式以及它们之间的关系和约束。XSD是W3C&#xff08;万维网联盟&#xff09;推荐的标准之一&#xff0c;它比早期的DTD&#xff08;Doc…

Ubuntu服务器中MySQL如何进行主从复制

一、MySQL 主从复制基本原理 MySQL 主从复制是指&#xff1a;一台数据库服务器负责写入操作&#xff0c;并将数据变更以二进制日志形式记录下来;一台或多台从库通过读取主库的二进制日志&#xff0c;实时或半实时地将主库的写入操作同步到自身数据库&#xff0c;实现数据一致性…

Android图形系统框架解析

前言 Android图形系统对于开发者来说可能会比较难以理解&#xff0c;因为涉及的东西可能会计较多&#xff0c;比如Android自己的图形系统。OpenGL&#xff0c;视频编解码器&#xff0c;SurfaceFlinger&#xff0c;FrameBuffer等等。下面我们结合官方文档&#xff0c;介绍一下图…

AI智能巡检系统给烘焙店开的「减损药方」 InfiSight智睿视界

01 食材浪费&#xff1a;甜蜜产业的苦涩成本 后厨操作台上&#xff0c;刚过最佳赏味期的可颂成批倒入垃圾桶——这是烘焙店最隐秘的痛。现烤现售模式虽保障新鲜度&#xff0c;却让原料管理沦为盲区&#xff1a; 销售数据≠生产指南&#xff1a;总部无法感知门店实时库存 …

工具 | vscode 发出声音,如何关闭

设置->搜 accessibility -> Accessibility Support -> 自动 改为 off 设置->搜 volume -> 0 设置->搜 sound -> 辅助功能信号 -> sound的 自动 改为 off 参考&#xff1a; How to turn off (or on) sounds from Visual Studio Code? - Stack Ove…

Hyperf 数据库事务指南(PHP 框架)

Hyperf 数据库事务指南&#xff08;PHP 框架&#xff09; 1. ⚙️ 数据库配置 1.1 配置文件 MySQL 配置位于 config/database.php&#xff0c;通常通过环境变量&#xff08;.env&#xff09;管理敏感信息&#xff1a; <?phpdeclare(strict_types 1); /*** This file i…

动态ds-vnp之normal和shortcut两种方式配置案例

normal方式配置 hub配置 dhcp enable interface GigabitEthernet0/0/0 ip address 3.3.3.3 255.255.255.0 interface GigabitEthernet0/0/1 ip address 192.168.3.254 255.255.255.0 dhcp select interface interface Tunnel0/0/0 ip address 10.1.1.3 255.255.255.0 tunnel…

ubuntu20.04调试livox aiva驱动获取激光雷达数据

实验环境ubuntu20.04 平台包括本地x86平台和jetson orin平台都测试ok 参考 ubuntu20.04上获取Livox Avia雷达点云数据 1.下载相关资料 下载包括&#xff1a;Livox Avia 用户手册中文.pdf、Livox_Viewer_For_Linux_Ubuntu16.04_x64_0.10.0&#xff08;用于显示激光雷达数据&am…

VS2022 C#【自动化文件上传】AutoFileUpload 新需求 V13

这里写自定义目录标题 需求分析实现方法原来&#xff08;需要修改的位置&#xff09;替换为如下代码&#xff08;添加三行数据&#xff09; 需求 现在已有程序&#xff1a;AutoFileUpload 存储excel表中时间列的第一列的列名到数据库中 分析 user只是想存储列名到数据表列去…

技术QA | ADC/DAC芯片测试研讨会笔记请查收!

6月19日&#xff0c;《ADC/DAC芯片测试前沿&#xff1a;德思特ATX系统高效方案与实战攻略》线上研讨会圆满结束。感谢大家的观看与支持&#xff01; 在直播间收到一些观众的技术问题&#xff0c;我们汇总了热点问题并请讲师详细解答&#xff0c;在此整理分享给大家&#xff0c…

区块链技术未来的发展趋势

以下是区块链技术未来的一些发展趋势&#xff1a; 技术层面 - 性能提升&#xff1a;分片技术会不断成熟和完善&#xff0c;将区块链网络划分为多个分片&#xff0c;每个分片独立处理交易&#xff0c;以提高交易吞吐量和网络可扩展性。同时&#xff0c;共识机制也会持续创新&a…

电商领域企业级应用后端开发 (Java) 就业前景深度分析报告 (2025-2030)

目录 一、行业概述与发展趋势 1.1 电商行业发展现状与趋势 1.2 电商技术架构演进与趋势 二、电商领域 Java 开发岗位需求分析 2.1 岗位数量变化趋势 2.2 岗位地域分布特点 2.3 岗位层级与职责变化 三、电商领域 Java 开发人才竞争分析 3.1 人才供需状况 3.2 人才竞争核…

DVWA Brute Force漏洞深度分析与利用指南

DVWA简介 DVWA&#xff08;Damn Vulnerable Web Application&#xff09;是一个基于PHP/MySQL的脆弱性Web应用平台&#xff0c;专为安全专业人员设计&#xff0c;用于测试技能和工具。它包含十大安全模块&#xff0c;其中Brute Force&#xff08;暴力破解&#xff09;是最基础…

【Android】Activity 的生命周期和启动模式

文章目录 Activity 的生命周期和启动模式1. 任务和返回栈2. Activity 的四种状态2.1 运行状态2.2 暂停状态2.3 停止状态2.4 销毁状态 3. Activity的生命周期3.1 生命周期回调方法3.2 演示 Activity 的生命周期 4. Activity的启动模式4.1 standard&#xff08;标准模式&#xff…

八大架构宪法 - 技术使用指导说明文档

我们定义了八部宏伟的“架构宪法”,这份 《八大架构宪法技术使用指导说明文档》,将作为交付给人类架构师和高级AI代理的 “战术手册”。 核心目标是:将每一部宪法的抽象哲学,转化为在项目不同阶段中、具体的、可操作的技术决策指南。回答一个关键问题:“在选择了某一部宪…