一、auto_ptr
auto_ptr是一种简单的智能指针,它被包含在<memory>中,它的基本原理就是利用类对象在函数结束时自动调用类里的析构函数。它的作用就是动态地分配对象,在对象不需要时自动地进行清理,同时,它的特点有以下几点:
(1)一个auto_ptr指向的空间,只能有一个auto_ptr指向,不能有多个auto_ptr去指向这个空间。当第二个auto_ptr指向同一块空间时,第一个auto_ptr的state变为false表示其无权限对指针进行操作,并且通过state使最后析构时,只进行一次析构。但是,它最大的缺憾也在这,虽然state表示它不能修改指针内容,但是我们仍然可以访问并修改这个空间的内容。
(2)一个auto_pr只能指向由用户自己开辟的空间,即在堆上的空间,这样才需要它去自动析构。
下面是对anto_ptr的具体实现,其有两种实现方法,其一,是使用一个bool类型的state值,当auto_ptr中state为true时,才可以使用,否则,不能使用。
下面是基于原版的代码和我自己改善的代码如下:
#ifndef _AUTO_PTR_H
#define _AUTO_PTR_H
#include<iostream>
using namespace std;
#define THROW cerr<<"失败。"<<endl
template<class T>
class auto_ptr
{
public:
auto_ptr(T *x = NULL)
{
if(x != NULL)
{
ptr = new T();
ptr = x;
state = true;
}
else
state = false;
}
~auto_ptr()
{
if(state)
delete ptr;
}
auto_ptr<T>& operator=(const auto_ptr<T>& other)
{
if(&other != this)
{
if(ptr != other.get())
{
//判断被赋值的指针原来是否指向空间,进行删除
if(state)
delete ptr;
}
if(other.state)
ptr = other.release();
else
THROW;
}
return *this;
}
/////////////////////////////////////////////////////////////////
//星号运算符重载
T& operator*() const
{
return *get(); //返回引用后的值
}
//箭头运算符重载
T *operator->() const
{
return get(); //返回指向的指针
}
T *get() const
{
return ptr;
}
//释放指针,使指针不再具有指向原地址的权限
T *release() const
{
/*
** mutable state = false; 两种方法修改从const的成员的值
*/
((auto_ptr<T> *)this)->state = false;
return ptr;
}
/////////////////////////////////////////////////////////////////
private:
bool state;
T *ptr;
};
#endif
我自己通过省去state,当有赋值和拷贝构造时,自动将前一个auto_ptr转为指向NULL,再在析构里面添加判断ptr是否为空进行delete操作,达到auto_ptr的效果。代码如下:
#include<iostream>
using namespace std;
template<typename T>
class my_auto_ptr
{
public:
//构造函数
my_auto_ptr() :ptr(NULL)
{}
my_auto_ptr(const T *x) :ptr((T *)x)
{}
//拷贝构造函数
my_auto_ptr(my_auto_ptr &other)
{
if (&other != this)
{
if (other.ptr == NULL)
ptr = NULL;
else
{
ptr = other.ptr;
other.ptr = NULL;
}
}
}
//赋值函数重载
my_auto_ptr& operator=(my_auto_ptr &other)
{
if (&other != this)
{
if (other.ptr == NULL)
ptr = NULL;
else
ptr = other.ptr;
}
other.ptr = NULL;
return *this;
}
//运算符的重载
T* operator->()
{
return ptr;
}
T& operator*()
{
return *ptr;
}
T* get()
{
return ptr;
}
~my_auto_ptr()
{
if (ptr)
delete ptr;
}
private:
T *ptr;
};
int main()
{
char *str2 = "lianyiming";
char *a = new char[11];
strcpy(a, str2);
//无参数构造str
my_auto_ptr<char> str;
//传参数构造str1
my_auto_ptr<char> str1(a);
cout << *str1.get() << endl;
//拷贝构造创建,将str1拷贝str3,此时str1变为NULL
my_auto_ptr<char> str3(str1);
cout << *str3.get() << endl;
//赋值实现,将str3赋值传给str,此时str3变为NULL
str = str3;
cout << *str.get() << endl;
return 0;
}