[ C++ ] — 智能指针

本文介绍了C++中的三种智能指针:auto_ptr(已废弃)、unique_ptr和shared_ptr,用于自动管理动态内存,防止内存泄漏和悬挂指针。unique_ptr采用独占所有权模型,不允许复制,而shared_ptr可共享所有权,通过引用计数管理内存。选择智能指针时,若需多个指针共享对象,使用shared_ptr;否则,推荐使用unique_ptr。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、三种智能指针

  • auto_ptr
  • unique_ptr
  • shared_ptr

(auto_ptr是C++98提供的方案,C++11已经将其摒弃,以下只是示例,实际不要使用auto_ptr)

使用new和delete管理动态内存常出现的问题:
(1)忘记delete内存
(2)使用已经释放的对象
(3)同一块内存释放两次

这三种智能指针模板都定义了类似指针的对象,可以将new获得的地址赋给这种对象。当智能指针过期时,其析构函数将使用delete释放内存(内存被自动释放,无需手动delete)。

  • 智能指针模板位于名称空间中。
  • 要创建智能指针,必须包含头文件memory

二、使用智能指针

  • 可以对智能指针执行解引用操作( *ptr );
  • 可以用它来访问结构成员(ps->next);
  • 将它赋给指向相同类型的常规指针
  • 将智能指针对象赋给另一个同类型的智能指针对象时需要注意(unique_ptr和shared_ptr不同,下面会讲)
auto_ptr<typename> pd(new typename);
auto_ptr<double> pd(new double);
auto_ptr<string> pd(new string);

其中 new typename 是new返回的指针,指向新分配的内存块,是构造函数auto_ptr<double> 的参数。

#include <iostream>
#include <string>
#include <memory>
using namespace std;

class Report{
private:
	string str;
public:
	Report(const string s) : str(s){
		cout<<"Object created! \n";
	}
	~Report(){
		cout<<"Object deleted!\n";
	}
	void comment() const{ cout<<str<<"\n";}
};
int main(){
	{
		auto_ptr<Report> ps(new Report("uing auto_ptr"));
		ps->comment();
	}
	//ps的作用域在代码块内
	{
		shared_ptr<Report> ps(new Report("uing shared_ptr"));
		ps->comment();
	}
	//ps的作用域在代码块内
	{
		unique_ptr<Report> ps(new Report("suing unique_ptr"));
		ps->comment();
	}
}

输出如下:
在这里插入图片描述
注意

  1. 所有指针都有一个explicit构造函数,该构造函数将指针作为参数。因此一下操作是不合法的:
shared_ptr<double> pd;
double* p =new double;
pd = p_reg; //非法
shared_ptr<double> pshared = p_reg;//非法
pd = shared_ptr<double>(preg); //合法
shared_pte<double> pshared(p_reg); //合法
  1. 不要用指向非堆内存的指针初始化智能指针对象,因为这将导致delete释放非堆内存,这是错误的。
string vacation("I love you.");
shared_ptr<string> pd(&vacation); //错误

三、unique_ptr指针

unique_ptr指针使用所有权模型,即对于特定的对象,只能由一个智能指针可拥有它,只有拥有对象的智能指针的构造函数会删除该对象。

unique_ptr<string> p1(new string("auto"));
unique_ptr<string> p2;
p2=p3; //报错

第三句会报错,编译器认为其非法。因为p2接管string对象后,p1的所有权将被剥夺,也就是p1不再指向有效数据。如果程序随后试图使用p1,将会发生问题。

但如果源unique_ptr是个临时右值,编译器允许这样做,
在这里插入图片描述
语句#2调用unique_ptr的构造函数的创建临时对象在将其所有权转让给pu3后就会被销毁。
在这里插入图片描述
C++的标准库函数std::move()让您能够将unique_ptr赋给另一个
在这里插入图片描述

四、shared_ptr指针

shared_ptr指针可以跟踪引用特定对象的智能指针数,赋值时,计数将+1,而指针过期时,计数-1。仅当最后一个指针过期时,才调用delete。
shared_ptr指针允许多个智能指针指向同一个对象。

五、选择智能指针

  • 如果程序要使用多个指向同一个对象的指针,应选择shared_ptr
  • 如果程序不需要多个指向同一个对象的指针,则可使用unique_ptr。

unique_ptr

  • 不使用new 或 new[ ] 分配内存时,不能使用unique_ptr

shared_ptr

  • 使用new分配内存时,才能使用shared_ptr
  • 使用new[ ]时,不能使用它
  • 不使用new分配内存时,不能使用它
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值