Class auto_ptr

C++标准程序库提供的auto_ptr是一种智能型指针,帮助程序员防止“被异常抛出时发生资源泄漏”。注意我说的是“一种”智能型指针,现实生活中还有其余许多有用的智能型指针,auto_ptr只是针对某个特定问题而设计的,对于其余问题,auto-ptr无能为力。ios

1、auto_ptr的设计动机:
函数的操做常常须要依如下模式进行:
一、获取一些资源。
二、执行一些操做。
三、释放所得到的资源。
     假如函数一开始得到的资源被绑定在局部对象身上,当函数退出时,他们的析构函数被调用,从而自动释放这些资源。可是若是函数一开始得到的资源是以显式手法(好比说:new)得到,那就必须以显示手法(好比说:delete)释放。可是有时候会忘记delete或者异常一旦发生,函数马上退出,根本执行不到函数尾端的delete语句,这就可能形成内存泄漏。固然你能够在函数中实现捕捉全部异常。但会使得函数变得十分复杂且容易出错。
    若是使用智能型指针能保证在任何一种状况下,只要本身被摧毁,就必定连带释放其所指的资源(由于智能型指针原本就是局部变量,因此不管是正常退出,仍是异常退出,都能保证该指针被销毁从而释放资源)。程序员

注意点:
    一、auto_ptr是这样一种指针:他是“他所指向的对象”的拥有者。因此,当身为对象拥有者的auto_ptr被摧毁时,该对象也将遭到摧毁。auto_ptr要求一个对象只能有一个拥有者。再也不须要delete,也再也不须要catch。
    二、auto_ptr拥有权是能够转移的:函数

std::auto_ptr<ClassA> ptr1(new ClassA);
std::auto_ptr<ClassA> ptr2(ptr1);
或者
std::auto_ptr<ClassA> ptr1(new ClassA);
std::auto_ptr<ClassA> ptr2;
ptr2 = ptr1;

在第一个语句中,ptr1拥有了那个new出来的对象。在 第二个语句中,拥有权由ptr1转交给ptr2。此后ptr2即拥有了那个new出来的对象,而ptr1不在拥有他。这样,对象就只会被delete一次(在ptr2被摧毁时)。
    若是ptr2在转交拥有权以前拥有另外一个对象,则转交操做执行以前会先调用delete,将ptr2所拥有的对象先摧毁。spa

std::auto_ptr<ClassA> ptr1(new ClassA);
std::auto_ptr<ClassA> ptr2(new ClassA);
ptr2 = ptr1; //ptr2以前拥有的对象被销毁,ptr1将第一个new出来的对象的拥有权转交给ptr2,ptr1为NULL。

    特殊用法:某个函数能够利用auto_ptr将拥有权转交给另外一个函数。这种状况可能出如今两种状况:
        a、auto_ptr被以传值的方式被看成一个参数传递给某个函数。此时被调用函数的参数就得到了这个auto_ptr的拥有权。设计

void sink(std::auto_ptr<ClassA>);

    b、当auto_ptr被看成返回值返回时,将拥有权转交给调用端。指针

std::auto_ptr<ClassA> fun()
{
    std::auto_ptr<ClassA> ptr(new ClassA);
    ...
    return ptr;
}

void gun()
{
    std::auto_ptr<ClassA> ptr;
    for (int i=0; i<10; i++)
    {
        p = fun(); //一旦进入循环再次执行赋值动做,意味着ptr先前拥有的对象被销毁了。
        ...
    }
}

三、const std::auto_ptr<class T> ptr;ptr的拥有权不容许被转移。在这里,关键词const并不是意味着你不能更改auto_ptr所拥有的对象,而是意味着你不能更改auto_ptr的拥有权。例如:code

std::auto_ptr<int> f()
{
    const auto_ptr<int> p(new int);
    auto_ptr<int> q(new int);
    *p = 42;    //ok
    q = p;      //error
    p = q;      //error
    return p;   //error
}

四、并不存在针对array设计的auto_ptr。由于auto_ptr是透过delete而非delete[]来释放其所拥有的对象。
五、auto_ptr不知足STL标准容器的对其元素的要求。由于在拷贝和赋值动做以后,本来的auto_ptr和新产生的auto_ptr并不相等。本来的auto_ptr会交出拥有权,而不是拷贝给新的auto_ptr。
六、auto_ptr不是引用计数型的指针——这种指针保证,若是有一组智能型指针指向同一个对象,那么当且仅当最后一个智能型指针被注销时,该对象才会被摧毁。对象

运用实例:内存

#include <iostream>
#include <memory>
using namespace std;

template <class T>
ostream& operator<< (ostream& strm, const auto_ptr<T>& p)
{
    if (NULL == p.get())
    {
        strm << "NULL";
    }
    else
    {
        strm << *p;
    }

    return strm;
}

int main()
{
    auto_ptr<int> p(new int(42));
    auto_ptr<int> q;

    cout << "after initialization:" << endl;
    cout << "p: " << p << endl;
    cout << "q: " << q << endl;

    q = p;
    cout << "after assigning auto pointers:" << endl;
    cout << "p: " << p << endl;
    cout << "q: " << q << endl;

    *q += 13;
    p = q;
    cout << "after change and reassignment:" << endl;
    cout << "p: " << p << endl;
    cout << "q: " << q << endl;

    return 0;
}

注意:output操做符的第二个参数是一个const refernce,因此并无发生拥有权的转移。
七、不能以通常指针的赋值手法来初始化一个auto_ptr:资源

std::auto_ptr<int> p(new int(42));     //OK
std::auto_ptr<int> p = new int(24);    //ERROR

p = std::auto_ptr<int>(new int(24));   //OK
p = new int(24);                       // ERROR

下面一个例子展现const auto_ptr的特性:

#include <iostream>
#include <memory>
using namespace std;

template <class T>
ostream& operator<< (ostream& strm, const auto_ptr<T>& p)
{
    if (NULL == p.get())
    {
        strm << "NULL";
    }
    else
    {
        strm << *p;
    }

    return strm;
}

int main()
{
    const auto_ptr<int> p(new int(42));
    const auto_ptr<int> q(new int(0));
    const auto_ptr<int> r;

    cout << "after initialization:" << endl;
    cout << "p: " << p << endl;
    cout << "q: " << q << endl;
    cout << "r: " << r << endl;

    *q = *p;
    //*r = *p;    //ERROR:undefine behavior
    *p = -77;
    cout << "after assigning auto pointers:" << endl;
    cout << "p: " << p << endl;
    cout << "q: " << q << endl;
    cout << "r: " << r << endl;

    //q = p;    //ERROR at compile time
    //r = p;    //ERROR at compile time

    return 0;
}

注意下列赋值操做是错误的:     *r = *p; 这个句子对于一个“未指向任何对象”的auto_ptr进行提领操做。C++标准规定,这会致使未定义行为,好比说致使程序的崩溃。

相关文章
相关标签/搜索