C++智能指针auto_ptr和nuique_ptr

来源:互联网 发布:vba编程从入门到精通 编辑:程序博客网 时间:2024/06/03 20:22

        在平时编码过程中,程序员操作资源这块是很频繁的一件事,一般对于堆内存等资源,我们需要手动申请和释放。但是,由于代码的频繁改动,很容易造成内存泄露,而这种内存泄露的大部分原因是因为对应的资源没有释放。例如,指针指向的一块内存,其释放操作在函数的尾部,但是中间由于其他条件,直接返回了,因此其尾部释放资源的操作无法执行。进而导致了资源泄露。而C++中的智能指针就是出于解决这类问题而诞生的。

        智能指针其本质是一个类,内部封装了一些成员函数的操作,要使用智能指针需要添加<memory.h>,智能指针总共分为4类,分别为auto_ptr、unique_ptr、shared_ptr和weak_ptr。

        先说auto_ptr,属于C++98的产物,它的用法和我们一般的指针用法有所不同,原因是它提供了一个拷贝构造函数。因此,在构造对象的时候,不能像一般指针使用方式去使用。应该如这种方式使用:auto_ptr<Base>basePtr(newDerive);同时,它提供reset()接口,用作释放当前的对象,并会将该对象进行析构。下面举例说明:

class Base{public:intvala,valb;Base(inta,int b){function();}Base() {function(); } virtual ~Base() {     cout<<"执行了base的析构函数"<<endl;}virtual void function()  {cout<<"this is base"<<endl; }};class Derive :public Base{public:intvala,valb;Derive(inta,int b): Base(a,b) {         vala = a;valb = b;function();sort();     }Derive(){        // sort();     };    ~Derive(){cout<<"执行了dericve的析构函数"<<endl;    }void function(){       cout<<"this is device function"<<endl; }virtualint sort() {cout<<"测试一下"<<endl;return 1;     }};int _tmain(intargc, _TCHAR* argv[]){auto_ptr<Base>basePtr(new Derive);basePtr->function();basePtr.reset();         return 0;}

执行结果为:


上述代码中,我们调用了reset()函数接口,可见我们的对象得到了析构,但是,值得注意的一个地方是,auto_ptr中有一个release()接口,我们调用这个接口效果为:


可见,release()接口并未析构对象,而只是单纯的释放对当前对象的控制。所以,如果我们需要手动释放对象的时候,一定要用reset()接口,而不是release()接口,否则一样会造成泄露。当然,既然使用了智能指针,我们应该将这种事情交给指针自己处理是最好的。

auto_ptr不提供对对象的共享,即不能像指针一样,多个指针指向同一个对象,当一个auto_ptr给另外一个auto_ptr指针赋值时,其实是交出了自己对对象资源的所有权。而这个性质也决定了它并不能够真的像指针那样去使用。

Unique_ptr指针相比而言,是auto的加强版,由于auto_ptr没有提供delete[]的操作,所以我们无法使用auto_ptr进行数组的创建,而unique_ptr则提供了这个功能。

另外,unique_ptr和auto_ptr最大的区别就是它限制了智能指针之间的赋值,也就是我们说的所有权的转移。由于auto_ptr在转移对象所有权的时候,已释放资源所有权的指针并不能很好的释放自身。而且该指针在继续调用对象的接口,编译器却没有报错。所以,auto_ptr并不是一个安全的指针。

1 0
原创粉丝点击