C++智能指针

智能指针介绍

智能指针是行为类似于指针的类对象,但是这种对象还有其他的功能,那么我们为什么要使用智能指针呢?我们可以通过一个例子来看看

void remodel(std::string & str)
{
    std::string *ps = new std::string(str);

    ....
    str = ps;
    return ;
}

在这个代码中,我们调用了new运算符开辟了一块内存空间用于存放string类的字符串,并且定义了一个string类的指针指向这片内存空间,我们在使用new运算符时,通常需要和delete配套使用,但是在这个代码中我们可能忘记进行内存的释放,这样就会造成内存的泄漏,这时我们希望这个指针ps也有一个析构函数,在我们忘记进行内存释放时,系统能够自动的进行空间的释放,这时候这个指针ps就不是一个普通的指针,而应该是一个类的对象,我们才能根据它去调用我们的析构函数,因此,我们的想法就是将一个普通的类指针更换为一个智能指针模版类,C++给我们提供了3个智能指针模版类,即如下

auto_ptr(C++98标准,已经被摒弃)

unique_ptr

shared_ptr

使用智能指针

这3个智能指针模版(即auto_ptr,unique_ptr,shared_ptr)都定义了类似指针的对象,可以将new直接或者间接获得的地址赋值给这种对象,当智能指针过期时,其析构函数都会使用delete来释放内存空间,因此,如果我们将new返回的地址赋给这些对象,我们就不需要再在智能指针过期时去对它们进行手动释放,系统会调用它们的析构函数进行自动释放,智能指针的用法如下所示,以auto_ptr为例

因为我们上面所示的这三个智能指针都是模版类,并且还需要包含头文件memory

auto_ptr<double> pd(new double);
auto_ptr<string> ps(new string);

因此,我们需要确定它的类型,作为一个实际的类auto_ptr<double>才能创建对象,在这里new double是new返回的指针,指向新开辟的内存块,它是构造函数auto_ptr<double>的参数,另外两个智能指针的用法也相同

我们可以通过编写一个例子,来体会一下智能指针的用法,我们定义一个类,并且只实现它的构造函数和析构函数,并根据输出的结果来判断我们的指针智能是否会去调用析构函数,代码如下

#include<iostream>
#include<string>
#include<memory>

using namespace std;

class Report
{
	private:
		string str;
	public:
		Report(string s):str(s){cout<<"Object created \n";}
		~Report(){cout<<"Object deleted \n";}
		void show()const {cout<<str<<endl;}
};
int main()
{
	auto_ptr<Report>pd (new Report("using auto_ptr"));
	
	return 0;
}

运行结果如下:

根据这个结果我们可以看出,这个智能指针自动的去调用了我们的析构函数,虽然在我们的析构函数中什么也没有做,并且在编译阶段,编译器给出了警告,告知了我们auto_ptr这个模版类已经被摒弃了,我们可以更好其他的模版类来体会一下智能指针调用析构函数的过程,这样编译器就不会给出警告

注意,我们所有的智能指针类都有一个explicit构造函数,该构造函数将指针作为参数,因此我们不需要自动将指针转换为智能指针对象,如下所示

shared_ptr<double> ps ;
double *p = new double;
ps = p; //这是不被允许的,explicit关键字禁止进行自动转换(隐式转换)

pd = shared_ptr<double>(p);//允许,explicit关键字允许显式类型转换

注意:使用unique_ptr时,我们尝试将一个unique_ptr赋给另外一个时,如果源unique_ptr是一个临时的右值,那么编译器允许这样做,如果unique_ptr会存在一段时间,那么编译器不允许,因为赋值之后新的unique_ptr会接管原来的unique_ptr,源unique_ptr会成为一个悬挂指针,如果我们要重新使用这个悬挂的指针,我们需要使用标准库函数std::move(),让这个指针指针指向一个新值,这样第二种操作就是被允许的

提示:

如果程序需要多个指向同一个对象的指针,则使用shared_ptr指针

如果程序不需要多个指向同一个对象的指针,则使用unique_ptr指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值