本文介绍了智能指针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
请按任意键继续. . .