auto_ptr智能指针

gclxry

auto_ptr是一种智能指针,帮助程序员防止”被异常抛出时发生资源泄露“。auto_prt只是针对某个特定问题而设计,对于其他问题无能为力。新的c++里面已经不提倡使用auto_ptr了

当你在某个局部new出一些对象的时候,还没有正常的delete,中间抛出了异常,导致无法执行delete,从而导致了资源泄露。而auto_prt保证只要自己被销毁,就一定连带释放其所指向的资源。如:

void f()
{
    MyClass* ptr = new MyClass;
    try
    {
        ...
    }
    catch (...)
    {
        throw;
    }

    delete ptr;    // 当抛出异常时,代码根本不会执行到这里。
}

当使用auto_ptr,就不再需要delete了,当auto_ptr超出了作用域,会自动的回收资源。

    auto_ptr<MyClass> ptr(new MyClass);
    try
    {
        ...
    }
    catch (...)
    {
        throw;
    }

auto_ptr的接口与一般指针非常相似。*用来获取所指对象,->用来指向对象中的成员。但是它不能做指针算术。

注意:auto_ptr<> 不允许你使用一般指针惯用的赋值初始化方式,你必须使用数值来完成初始化。

auto_ptr<MyClass> ptr(new MyClass);            //    正确
auto_ptr<MyClass> ptr2 = new MyClass;        //    错误

auto_ptr是明确的所有观念。由于auto_ptr会删除其所指对象,所以这个对象绝对不能同时被其他对象拥有。绝对不应该出现多个auto_ptr同时拥有一个对象。所以auto_ptr的拷贝构造函数和赋值操作将交出对象的拥有权。

auto_ptr<MyClass> ptr1(new MyClass);
auto_ptr<MyClass> ptr2(ptr1);

第一个语句中ptr1拥有对象,第二个语句中ptr1将对象转交给ptr2,ptr1不再拥有。赋值也差不多

auto_ptr<MyClass> ptr1(new MyClass);
auto_ptr<MyClass> ptr2;

ptr2 = ptr1;

如果ptr2在赋值前拥有对象,那么赋值动作发生时会调用delete将对象删除。

拥有权的转移使得auto_ptr产生了一种特殊的用法:某个函数可以利用auto_ptr将拥有权转交给另一个函数。

向某个函数内传递auto_ptr,如果f不再将ptr1传递出去,那么它指向的对象将在f退出时销毁。

auto_ptr<MyClass> ptr1(new MyClass);

f(ptr1);

函数向外返回auto_ptr。这样,f中的auto_ptr指向对象所有权将转移到了g中。

auto_ptr<MyClass> f()
{
    auto_ptr<MyClass> ptr(new MyClass);
    return ptr;
}

void g()
{
    auto_ptr<MyClass> ptr = f();
}

auto_ptr语义本身就包含了拥有权,如果你无意转交了所有权,就不要用着函数的参数列表和函数返回值中。下面的例子中函数只是想打印出auto_ptr指向的值,却得到了对象的所有权。

template<class T>
void bad_print(auto_ptr<T> ptr)
{
    if (ptr.get() == NULL)
    {
        cout<<"NULL"<<endl;
    }
    else
    {
        cout<<*ptr<<endl;
    }
}

auto_ptr<int> p(new int);
*p = 42;
bad_print(p);    // 所有权转移到了bad_print函数中
*p = 18;        // 错误,它不再拥有所有权了

我们可以使用const来保留所有权,防止意外的转移:

const auto_ptr<int> p(new int);
*p = 42;
bad_print(p);    // 编译不过
*p = 18;

正确的打印:

template<class T>;
void good_print(T value)
{
    cout<<value<<endl;
}
    const auto_ptr<int> p(new int);
    *p = 42;
    good_print(*p);    // 不再传递指针
    *p = 18;        // 正确,依然拥有所有权
    good_print(*p);

auto_ptr的错误使用: auto_ptr 之间不能共享所有权 并不存在针对array而设计的auto_ptr,不要使用new[]所生成的数组作为初值。 auto_ptr不是一个通用的智能型指针 auto_ptr不满足stl容器对其元素的要求