C/C++中智能指针的用法详解 c++自动指针

   2023-02-08 学习力0
核心提示:目录前言一、什么是智能指针二、使用方法1.shared_ptr2.unique_ptr3.weak_ptr前言本章主要介绍一些C/C++中智能指针的实现原理以及如何使用一、什么是智能指针C/C++中,指针是一个非常重要的概念,其强大但也麻烦麻烦之处就在于一旦你申请了内存,那就必须要手

前言

本章主要介绍一些C/C++中智能指针的实现原理以及如何使用

一、什么是智能指针

C/C++中,指针是一个非常重要的概念,其强大但也麻烦

麻烦之处就在于一旦你申请了内存,那就必须要手动去释放内容,否则就会造成内存泄漏

当然了,在代码量少的情况下你可能会不以为意,因为这点内存即使泄露了也根本看不出来,而且一旦程序执行结束,所有内存都会被系统释放

但如果一旦写比较大点的项目,内存管理就显得很重要了,比如QQ,微信等等,一般都是一直挂着的

如果挂几个小时就把电脑内存耗干净了,瞬间电脑变卡,谁还用啊

所以智能指针的作用就是防止我们麻痹大意忘记释放内存,帮助我们管理内存的

当然也有多次释放一个指针,导致程序崩溃的问题也能就此解决

二、使用方法

虽然智能指针听着很高级,但使用起来并不算复杂,熟悉之后,其实和普通指针差别不大。但会更加好用

自C++11之后,智能指针共有三个:shared_ptr、unique_ptr、weak_ptr

1.shared_ptr

看名字就知道,它是可以分享的指针,其使用方法很简单:

比如这里有一个类:

class User {
public:
	User() {
		cout << "这是构造函数" << endl;
	}
	~User()
	{
		cout << "这是析构函数" << endl;
	}

	void TestFun() {
		cout << "这是一个测试函数" << endl;
	}

};

然后使用共享智能指针:

#include<iostream>
using namespace std;
//上面的那个类可以放在这里
int main() {
	shared_ptr<User> p(new User());
	shared_ptr<User> p1 = p;
	shared_ptr<User> p2 = p;

	p->TestFun(); //调用函数的方式和指针一样
	cout << p.use_count() << endl; //输出共享个数
}

即:通过模板参数,传入要构造的指针类型,然后在初始化的时候,就可以直接new一个对象即可

因为是共享的,所以它还能互相赋值,并可以用函数use_count返回当前共享的个数

其使用方法,如调用类的函数和属性之类的,就和普通的指针一样,用->进行调用即可,但是却不需要我们去亲自清理内存了!

C/C++中智能指针的用法详解

看,现在我们并没有清理内存,但这个类的析构函数却被调用了!这就说明内存已经被正常释放了

这就是智能指针的好处!

但智能指针写着有点麻烦,每次声明其类型都有一长串,所以一般我们会对指针进行重定义,达到简化的目的:

typedef shared_ptr<User> SPUser;
int main() {
    SPUser p(new User());
    SPUser p1 = p;
    SPUser p2 = p;
    p->TestFun(); //调用函数的方式和指针一样
    cout << p.use_count() << endl; //输出共享个数
}

2.unique_ptr

上面的共享指针的使用方法和普通指针区别并不大

但有时候,我们想要某个对象同时只能存在一份,即不允许像共享指针那样,可以到处随意赋值给别人

这时候就可以用unique_ptr,其使用方法如下:

typedef unique_ptr<User> UPUser; //重新定义一个名称,便于使用
int main() {
	UPUser p(new User);
	//UPUser p1 = p; //错误,不能进行赋值
	UPUser p2;
	p2.swap(p); //但可以交换,即p2现在保存有变量,但p变为了空指针
	if (p == nullptr) {
		cout << "p为空指针" << endl;
	}
	p2->TestFun(); //正常调用

	UPUser p3 = move(p2); //也可以用move函数移动
	if (p2 == nullptr) { //此时p2就是空指针
		cout << "p2为空指针" << endl;
	}
	p3->TestFun(); //p3则保存对象指针
}

C/C++中智能指针的用法详解

可以看到,它的使用方法其实和共享指针是差不多的,唯一不同之处就是,它内部的指针值,同一时刻只能存在一份

即,你不能对它进行任何形式的复制,但是可以移动

3.weak_ptr

这个智能指针用的不太多,因为它本身并没有太多实际的用途,而是主要作为shared_ptr的一个辅助类存在

比如有多少指向相同的 shared_ptr 指针、shared_ptr 指针指向的堆内存是否已经被释放等等。

其使用方法如下:

typedef shared_ptr<User> SPUser;
typedef weak_ptr<User> WPUser;
int main() {
	
	SPUser p(new User());
	SPUser p1 = p;
	SPUser p2 = p;

	WPUser wp(p);
	cout << wp.use_count() << endl; //查看这个共享指针使用次数
	cout << wp.expired() << endl; //判断这个指针是否为空,或者内存已经被释放

}

C/C++中智能指针的用法详解

原文地址:https://blog.csdn.net/weixin_50964512/article/details/128536406
 
标签: C++ 智能 指针
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Aurelius vs mORMot vs EntityDAC Delphi 的
    Aurelius vs mORMot vs EntityDAC   Delphi 的 ORM框架:http://www.tmssoftware.com/site/aurelius.asp#product-buy-onlinehttps://synopse.info/fossil/wiki/Synopse+OpenSourcehttps://www.devart.com/entitydac/download.htmlkbmMW  http://www.compo
    02-09
  • 【Ruby】Mac gem的一些坑
    前言自上一次升级MacOS系统后出现jekyll无法构建的问题,当时处理半天。谁知道最近又升级了MacOS,荒废博客多时,今天吝啬写了一篇准备发布,构建报错,问题重新。还是记录下,以防下次升级出问题。问题描述安装jekyll静态博客需要在Ruby环境下运行,于是参照
    02-09
  • iOS oc 调用 swift
    如股票oc要调用swift里面的代码 需要包含固定这个头文件项目名称 LiqunSwiftDemo-Swift.h         #ProjectName#-Swift.h固定的写法swift 目的 是取代oc 但是 不会完全取代 只是前端的替换LiqunSwiftDemo-Swift 点进去 可以看到 所有的swift代码 都产生
    02-09
  • objective-c NSTimer 定时器
    -(void)initTimer{//时间间隔NSTimeInterval timeInterval =3.0 ;//定时器repeats 表示是否需要重复,NO为只重复一次NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(mobileAnimation) userInfo:nil
    02-09
  • Objective-C  日记③ 字符串
    Objective-C 日记③ 字符串
    一、创建字符串、类方法   公式创建NSString  +(id) stringWithFormat:(NSString *) format,……;eg:  NSString *height;  height=[NSString stringWithFormat:@"高度是: %d 长度: %d",10,20];得到的字符串:“高度是: 10 长度: 20” 注意:  省
    02-09
  • Objective-C KVC机制
    Objective-C KVC机制http://blog.csdn.net/omegayy/article/details/7381301全部推翻重写一个版本,这是我在公司内做技术分享的文档总结,对结构、条理做了更清晰的调整。 1.    基本概念MODEL主要是英文文档里面经常出现的一些概念,讲解一下,方便英文
    02-09
  • objective-c 加号 减号 - +
    “加号代表static”是错误的说法,可能跟你那样表达的人其实意思是:“前置加号的方法相当于Java 里面的静态方法”。在Oc中,方法分为类方法和实例方法。前置加号(+)的方法为类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例。有人把
    02-09
  • Objective-C  日记①
    Objective-C 日记①
    1、Xcode的.m扩展名表示文件含有Object-C代码,C以.c文件,C++以.cpp文件2、头文件声明:C使用:#include,O-C使用#import(当然你也可以使用#include) 3、输出方式:  C:printf("",参数);  O-C:NSLog(@"",参数); 4、布尔类型  C:bool 具有true
    02-09
  • ASP.NET MVC 操作AD 获取域服务器当前用户姓
    #region 根据当前登录域账号 获取AD用户姓名和所在OU目录/// summary/// 根据当前登录域账号 获取AD用户姓名和所在OU目录/// /summary/// param name="searchUser"要搜索的当前用户名/param/// param name="paths"out返回该用户所在OU目录/param/// param nam
    02-09
  • swift和OC - 拆分数组 和 拆分字符串
    1. 拆分数组 /// 根据 数组 截取 指定个数返回 多个数组的集合func splitArray( array: [Date], withSubSize subSize: Int) - [[Date]] {//数组将被拆分成指定长度数组的个数let count = array.count% subSize == 0 ? (array.count/ subSize) : (array.count
    02-08
点击排行