c++中智能指针auto_ptr的简介以及使用方法

本文介绍了智能指针auto_ptr的基本概念和简单的使用方法,以及示例程序。然后根据智能指针的使用特点,自己定义了一个智能指针的模板类。以加深对智能指针的理解。

auto_ptr保证在异常被抛出时,分配的对象能够自动消费,内存能够自动释放。使用auto_ptr可以代替指针进行操作,并且不关心内存的释放。解决内存溢出的问题。

下面的程序包括auto_ptr一个简单的示例一级自定义的一个类模板smart_pointer,以便链接智能指针的底层实现的原理: 

测试源代码

#include "stdafx.h"
#include <iostream>
#include <string>
#include <memory>
#pragma warning(disable:4996)
using namespace std;

class test{
public:
	char *name;
	test(){
		cout << "constructor have not arg" << endl;
		name = NULL;
	}
	test(const char* str_name)
	{
		cout << "constructor have arg" << endl;
		name = new char[strlen(str_name) + 1];
		strcpy(name, str_name);
	}
	test& operator = (const char *str_name)
	{
		cout << "= overload" <<endl;
		if (NULL != name)
			delete name;
		name = new char[strlen(str_name) + 1];
		strcpy(name, str_name);
		return *this;
	}

	void show_name(void)
	{
		cout << "name:" << name << endl;
	}

	~test()
	{
		if (NULL != name)
			delete name;
		name = NULL;
		cout << "this ~test is called" << endl;
	}
};

//以下实现智能指针的类模板
template<typename T> class smart_pointer{
public:
	smart_pointer(T*p = 0);
	smart_pointer(const smart_pointer&ptr);
	smart_pointer& operator = (const smart_pointer&arg);
	T* operator -> ();
	T& operator * ();
	~smart_pointer();
private:
	void de_count(void)
	{
		if (--*count == 0)
		{
			delete c_ptr;
			delete count;
		}
	}
	T *c_ptr;//对象的指针
	int *count;//引用计数
};

template<typename T> smart_pointer<T>::smart_pointer(T *p)
{
	c_ptr = p;//c_ptr和p指向同一个内存
	count = new int(1);//初始值是1
}

template<typename T> smart_pointer<T>::smart_pointer(const smart_pointer<T> &ptr)
{
	c_ptr = ptr.c_ptr;
	count++;
	count = ptr.count;
}

template<typename T> smart_pointer<T>::~smart_pointer()
{
	de_count();//自身引用计数减一,如果减一后的引用计数为0,那么释放内存
	cout << "destructor " << endl;
}

template<typename T> smart_pointer<T>& smart_pointer<T>::operator = (const smart_pointer<T> &ptr)
{
	++*ptr.count;
	de_count();
	c_ptr = ptr.c_ptr;
	count = ptr.count;

	return *this;
}

template<typename T> T* smart_pointer<T>::operator -> ()
{
	if (c_ptr)
		return c_ptr;
	//如果c_ptr为空,抛出异常
	throw runtime_error("-> access NULL pointer");
}

template<typename T> T& smart_pointer<T>::operator *()
{
	if (c_ptr)
		return *c_ptr;
	//如果c_ptr为空,抛出异常
	throw runtime_error("* access NULL pointer");
}

int main(int argc, char *argv[])
{
	//以下是使用std中标准的智能指针auto_ptr
	cout << "follow code is auto_ptr:" << endl;
	auto_ptr<test> ap_test1(new test("xyz"));//调用test类中的带有参数的够着函数,对name成员赋值
	auto_ptr<test> ap_test2(new test("abc"));
	//auto_ptr<test> ap_test3 = new test("xyzw");//这里报错,不能使用这种方式对智能指针赋值

	ap_test1->show_name();
	ap_test2->show_name();//显示出当前name

	*ap_test1 = "apple";//调用重载运行算符=

	*ap_test2 = "banana";

	ap_test1->show_name();
	ap_test2->show_name();

#if 0
	/*以下的代码的目的是让程序执行异常,验证智能指针会在程序异常的时候制动释放所指向的内存*/
	int x = 1;
	int y = 0;
	cout << "follow will exception" << endl;
	throw runtime_error("this access NULL pointer");
	//x = x / y;
#endif

	//以下的代码使用的是自己实现的智能指针类模板smart_pointer
	cout << endl;
	cout << endl;
	cout << "follow code is smart_pointer:" << endl;
	smart_pointer<test> st1;
	smart_pointer<test> st2(new test("pear"));
	smart_pointer<test> st3(new test("orange"));

	try{
		st1->show_name();
	}
	catch (const exception &err)
	{
		cout << err.what() << endl;
	}

	st2->show_name();
	*st2 = "apple";
	st2->show_name();
	st3->show_name();

	st2 = st3;//调用运算符=重载原来的st2的对象引用为0,发生析构,st3的对象+1
	st2->show_name();


	return 0;

}

测试结果:

follow code is auto_ptr:
constructor have arg
constructor have arg
name:xyz
name:abc
= overload
= overload
name:apple
name:banana


follow code is smart_pointer:
constructor have arg
constructor have arg
-> access NULL pointer
name:pear
= overload
name:apple
name:orange
this ~test is called
name:orange
destructor
this ~test is called
destructor
destructor
this ~test is called
this ~test is called
请按任意键继续. . .

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章