C++,智能指针详解

为什么要使用智能指针?

在我们使用指针的时候,在分配了内存之后我们有时会忘记了释放内存,但造成内存泄漏对于一个程序员来讲简直是一个巨大的噩耗.泄漏一点点内存是没啥影响,但如果是在一个循环中不断的消耗内存呢?当内存消耗完了之后就会宕机,这是我们一定要杜绝发生的,那怎么样才能避免此类的事情发生呢?

比如下面的代码就很容易造成内存泄漏,我们以为代码会朝着我们理想的方向走,不会发生文件打不开的情况,此时我们又需要在里面抛出一个异常的时候,这就造成了内存泄漏就悲剧了~!

//分配内存
int newMemory() {

	ifstream ostream;
	string* str = new string("内存泄漏很危险,要小心啊~");
	ostream.open("data.txt");
	if (!ostream.is_open()) {

		//to do....
		{
			throw exception("文件不存在");
		}
	}

	cout << *str << endl;
	delete str;//释放内存
	return 0;
}

为避免此类事情的发生,C++一众大牛们推出了"智能指针"这一概念,下面我就介绍一下智能指针:

1.auto_ptr.

auto_ptr 是C++98 定义的一个智能指针模板,他为我们提供了更为有效的对指针对象的管理,它可以将new获得的直接(间接)地址交给它来管理.当我们使用的对象生命周期结束时,它会自动的调用析构函数使用delete释放内存,这时候你再也不用担心内存泄漏了.

那么该如何使用呢?

我们需要包含头文件#include<memory> ,定义的数据类型可以是int,float,double,string,long long......也可以是自己的定义的一些数据类型.下面是我举例智能指针的定义:

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


    //定义了一个int类型智能指针对象age,并分配了10个int类型的数据
	auto_ptr<int> age(new int[10]);
	//定义了一个string类型的智能指针对象str
	auto_ptr<string> str(new string("大佬带带我!我很好带的~"));
	//定义了一个使用vector容器装载int类型的智能指针对象auV
	auto_ptr<vector<int>> auV(new vector<int>(10));

这些我们定义的智能指针对象,在他们的声明周期结束时,他们会被自动的调用析构函数使用delete释放内存.

智能智能虽然好用,但是我们也需要注意几个点:

1.尽量不要将auto_ptr智能指针定义为全局变量.要知道很多其他的变量我们也是不建议定义为全局变量的.

2.不要定义指向智能指针对象的指针变量.智能指针本身就是一个指针,所以不建议再次定义为指针.使用过程中这会发生一些不可预料的诡异问题.例如:

auto_ptr<int>* age;//不建议将智能指针定义为指针

auto_ptr<int>* age = new auto_ptr<int>(new int[10]);//不建议

//需要使用头文件
#include<memory>//auto_ptr
#include<vector>


//这是一个仅供举例说明的类
class Test {
public:
	Test() {

	}

	~Test() {

	}

	int getDebug() {
		return debug;
	}

private:
	int debug;
};


int main1(void) {

    //不要定义指向智能指针对象的指针变量
	auto_ptr<Test>* at = new auto_ptr<Test>(new Test());

}

3.不要把auto_ptr 智能指针赋值给同类型的另外一个智能智能指针,除非你知道这样做的后果,否则不建议这样做.例:

	auto_ptr<Test> t1;
	auto_ptr<Test> t2;
	t1 = t2;//不建议

下面是auto_ptr 的一些常见用法:

	//使用智能指针访问对象时,使用方式和普通指针一样,
	cout << "t1->getDebug()" << t1->getDebug() << endl;
	cout << "(*t1).getDebug()" << (*t1).getDebug() << endl;

	
	//把t1的地址交给了tmp管理
	Test* tmp = t1.get();
	cout << "tmp->getDebug()" << tmp->getDebug() << endl;


	//release 取消指针对动态内存的托管,之前分配的内存需要使用delete手动释放!
	tmp = t1.release();
	delete tmp;

	//reset 重置智能指针托管的内存,如果地址不一致,之前的地址会被析构掉
	t1.reset();
	t1.reset(new Test());

另外说一下,auto_ptr 在 C++11 标准出来之后就被"抛弃"了,使用更安全的unique_ptr替代.大家会说这都不用了说还有什么用呢?

但了解auto_ptr可以更好的了解unique_ptr,后面我会讲一下unique_ptr。那今天的分享就到这里了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值