为什么当时无法引用智能指针auto_ptr?

时间:2013-01-01 12:46:45

标签: c++ pointers

#include <memory>
#include <iostream>

using namespace std;
class MyClass
{
public:
    int i;
    MyClass(int s) {
        i=s;
    }
    ~MyClass() {
        cout<<"This class has been destroied.  "<<i<<endl;
    }
    void myFunc() {
        cout<<"myFunc() done.  "<<i<<endl;
    }
};

int main()
{
    auto_ptr<MyClass> ptr1(new MyClass(1));
    auto_ptr<MyClass>ptr2(new MyClass(2));
    ptr1->myFunc();
    ptr2->myFunc();
    cout<<"test 1 done\n"<<endl;

    ptr2 = ptr1;
    ptr2->myFunc();
    //ptr1->myFunc();
    cout<<"test 2 done\n"<<endl;
}
/*
$ ./a.out 
myFunc() done.  1
myFunc() done.  2
test 1 done

This class has been destroied.  2
myFunc() done.  1
test 2 done
 * */

如果未注释掉上述ptr1->myFunc();,则结果如下。但我无法理解。我认为ptr1当时没有被破坏...... 谁能帮忙进一步解释呢?

$ ./a.out 
myFunc() done.  1
myFunc() done.  2
test 1 done

This class has been destroied.  2
myFunc() done.  1
Segmentation fault (core dumped)

2 个答案:

答案 0 :(得分:4)

旧的auto_ptr在复制或分配时有非常奇怪的行为。它具有传输语义而不是复制语义。这意味着,当您说ptr2 = ptr1;时,ptr1实际上发生了变化:它不再指向任何事物。 (ptr2最初指向的东西当然已被删除。)

因此,在您从分配之后,不得使用ptr1(直到再次将分配给或重置)。


事实上,这种行为是如此尴尬,虽然这种智能指针是一个非常理想的事情,但表明语言中缺少某些东西。正确的解决方案需要右值引用,并且尝试解决与unique_ptr相同问题的新auto_ptr表现得更明智:您根本无法复制或复制它,但您可以移动它 - 这是语言的新部分:

unique_ptr<MyClass> ptr1(new MyClass), ptr2(new MyClass);

ptr2 = std::move(ptr1);  // now it's clear that ptr1 is no longer usable

assert(!ptr1);

答案 1 :(得分:1)

执行ptr2 = ptr1;时,您正在删除ptr2当前指向的对象,该对象现在指向ptr1先前指向的对象。 ptr1已将自己设置为指向 null ,因为这是副本上auto_ptr的语义。然后,您尝试取消引用null,并且很幸运地遇到崩溃并且认为您的代码错误。