Chinaunix首页 | 论坛 | 博客
  • 博客访问: 116273
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 242
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-17 13:36
文章分类

全部博文(29)

文章存档

2015年(29)

我的朋友

分类: C/C++

2015-04-20 22:28:23

智能指针

智能指针的作用:智能指针在退出某个作用域时,能够将在对中开辟的空间自动释放掉,防止内存泄露。

智能指针与普通指针:

void f(){

    T* pt(new T);

    /*... more code ...*/

    delete pt;

}

如果f()没有执行delete语句(因为过早return或者是在函数体内抛出异常)。动态分配的对象将没有被delete,一个典型的内存泄露,使其安全的一个简单方法是用一个灵巧的类指针对象包含这个指针,在其析构时,自动删除指针:

void f(){

    auto_ptr<T> pt(new T);

    /*... more code ...*/

}

现在这个代码将不再泄露T对象了,无论是正常函数结束还是因为异常。因为pt的析构函数总是在退栈过程中被调用,类似的,auto_ptr可以被用来安全的包容指针。

class C{

public:

    C();

    /*......*/

private:

    auto_ptr<A> p_a;

};

//file c.cpp

C::C():p_a(new A){}

现在,析构函数不再需要删除p_a指针,因为auto_ptr会自动处理它。

 

如下为智能指针的使用案例:

#include

using namespace std;

class A

{

public:

    A(){cout << "A()" << endl;}

    ~A(){cout << "~A()" << endl;}

    void AShow(){cout << "This is AShow" << endl;}

};

 

void fun()

{

    auto_ptr<A> pa(new A);

    pa->AShow();

}

int main()

{

    fun();

    return 0;

}

输出如下:

A()

This is AShow

~A()

 

下面再来看一段代码,这段代码通过一个函数产生一个智能指针,并返回。

auto_ptr<A> GetAPtr()

{

    return auto_ptr<A>(new A);

}

int main()

{

    auto_ptr<A> pa = GetAPtr();

    pa->AShow();

    return 0;

}

输出的结果和上面一样,这里有个问题,在GetAPtr中,return的内容不进行强制类型转换是否可以,如下:return new A;

答案是不可行的,因为auto_ptr的构造函数定义如下:

explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()

        : _Myptr(_Ptr)

{    // construct from object pointer

}

大家知道,定义为explicit的构造函数不能用于隐式转换,所以,必须通过显示的强制类型转换实现。

 

下面,来自己实现一个智能指针类,并且,构造函数不为explicit类型。代码如下:

template<typename T>

class my_auto_ptr

{

public:

    my_auto_ptr(T* ptr):m_ptr(ptr){}

    ~my_auto_ptr(){if(m_ptr)delete m_ptr;}

    T* operator->(){return m_ptr;}

    T& operator*(){return *m_ptr;}

private:

    T* m_ptr;

};

 

int main()

{

    my_auto_ptr<A> pa(new A);

    pa->AShow();

    return 0;

}

代码很简单吧,输出为:

A()

This is AShow

~A()

和前面的一模一样。当然,我这边的代码只是把主要的部分给写了,真实的智能指针要比这个复杂一些,就不深究了。

此时重写GetAPtr函数如下:

my_auto_ptr<A> GetAPtr()

{

    return new A;

}

 

int main()

{

    my_auto_ptr<A> pa = GetAPtr();

    pa->AShow();

    return 0;

}

现在就不用显式转换了,编译能顺利通过。

 

阅读(946) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~