虽然unique_ptr保证在移动后存储nullptr,但它仍指向对象?

时间:2015-11-30 18:32:16

标签: c++ c++11 unique-ptr

我已经使用GCC 5.2(C ++ 11)测试了以下代码:

#include <iostream>
#include <memory>

struct Foo
{
    Foo()      { std::cout << "Foo::Foo\n";  }
    ~Foo()     { std::cout << "Foo::~Foo\n"; }
    void bar() { std::cout << "Foo::bar\n";  }
};

void f(const Foo &)
{
    std::cout << "f(const Foo&)\n";
}

int main()
{
    std::unique_ptr<Foo> p1(new Foo);  // p1 owns Foo
    if (p1) p1->bar();

    {
        //p1->bar();
        std::unique_ptr<Foo> p2(std::move(p1));  // now p2 owns Foo
        f(*p2);
        p1->bar();
        if(p1==nullptr)
        {
            std::cout<<"NULL"<<std::endl;
        }
        p1 = std::move(p2);  // ownership returns to p1
        std::unique_ptr<Foo> p3;
        p3->bar();
        std::cout << "destroying p2...\n";
    }

    if (p1) p1->bar();

    // Foo instance is destroyed when p1 goes out of scope
}

所以现在我的问题是,虽然p1在移动操作后保证为nullptr,但它似乎仍指向前一个对象?

编辑: 是的,我问为什么p1-&gt; bar();给定p1已经移动仍然工作,而bar()不是静态函数。 正如大家所指出的那样,未定义的行为会导致任何事情发生。 我现在遇到了足够的未定义行为......如果有人能指出我在C ++ 11中常见的未定义行为的集合,我将不胜感激。 提前谢谢。

1 个答案:

答案 0 :(得分:6)

我假设你指的是这个:

std::unique_ptr<Foo> p2(std::move(p1));  // now p2 owns Foo
p1->bar();

并输出&#34; Foo :: bar&#34;?

嗯,它应该做什么呢?您正在取消引用无效指针。 Anything can happen

在这种情况下,由于您没有访问不存在的Foo的任何成员,因此您将成为一个不可思议的成员。幸运的是在这里遇到了崩溃(因为,在较低级别,没有实际的&#34;物理&#34;解除引用0x0需要发生。)

但它并没有改变what you're doing is wrong

这一事实