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

 更新时间:2023年01月04日 10:32:23   作者:余识-  
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返回当前共享的个数

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

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

这就是智能指针的好处!

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

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则保存对象指针
}

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

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

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++中智能指针的用法详解的文章就介绍到这了,更多相关C++智能指针内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现迷宫游戏

    C++实现迷宫游戏

    这篇文章主要为大家详细介绍了C++实现迷宫游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 解决了个困扰了2天的问题,定点运算问题

    解决了个困扰了2天的问题,定点运算问题

    本文主要讲解定点运算问题,需要的朋友可以参考一下。
    2016-06-06
  • OpenCV外接USB摄像头的方法

    OpenCV外接USB摄像头的方法

    这篇文章主要为大家详细介绍了OpenCV外接USB摄像头的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • C++ 私有析构函数的作用示例详解

    C++ 私有析构函数的作用示例详解

    这篇文章主要介绍了C++ 私有析构函数的作用,私有析构函数不会影响栈上对象的自动析构,它们会在其作用域结束时自动调用析构函数。私有析构函数主要影响的是对堆上对象的显式删除操作,需要的朋友可以参考下
    2023-06-06
  • C++ seekg函数用法案例详解

    C++ seekg函数用法案例详解

    这篇文章主要介绍了C++ seekg函数用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C++实现五子棋小游戏

    C++实现五子棋小游戏

    这篇文章主要为大家详细介绍了C++实现五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C语言实现简单反弹球消砖块游戏

    C语言实现简单反弹球消砖块游戏

    这篇文章主要为大家详细介绍了C语言实现简单反弹球消砖块游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C++继承介绍

    C++继承介绍

    C++继承可以是单一继承或多重继承,每一个继承连接可以是public,protected,private也可以是virtual或non-virtual
    2013-01-01
  • C语言中bool变量的深入理解

    C语言中bool变量的深入理解

    C语言中没有BOOL类型变量,它是C++独有的,由于使用BOOL类型可以使代码更具有可读性,下面这篇文章主要给大家介绍了关于C语言中bool变量的相关资料,需要的朋友可以参考下
    2021-08-08
  • C语言采用文本方式和二进制方式打开文件的区别分析

    C语言采用文本方式和二进制方式打开文件的区别分析

    这篇文章主要介绍了C语言采用文本方式和二进制方式打开文件的区别分析,有助于读者更好的理解文本文件与二进制文件的原理,需要的朋友可以参考下
    2014-07-07

最新评论