如果我取一个unique_ptr的原始指针,然后使用reset,是否仍然保证原始指针有效?

If I take a raw pointer of a unique_ptr and then use reset, is the raw pointer still guaranteed to be valid?

例如,我很确定这行得通。

int foo = 51;
int* bar = &foo;
foo = 3;

所以bar仍然有效,并且*bar == 3

如果我们说

std::unique_ptr<int> foo(new int(51));  // should probably use make_unique
int* bar = foo.get();
foo.reset(new int(3));

我能保证*bar == 3吗? 还是我继续引用 bar 导致了未定义的行为?

不,一点也不。你会得到未定义的行为,因为 unique_ptr 管理的原始指针被 reset 改变了。事实上,unique_ptr 删除了托管指针并重新分配了一个新指针,因此您的旧指针将继续指向旧地址,该地址不再有效。您的代码等同于:

#include <iostream>

int main()
{
    int* managed = new int(51); // equivalent to unique_ptr(new int(51));
    int* bar = managed; // equivalent of unique_ptr::get
    delete managed; managed = new int(3); // equivalent to unique_ptr::reset(new int(3))
    std::cout << *bar << std::endl; // Wrong!!! Undefined behaviour, bar is dangling!
}

你的第一个代码片段确实是正确的,因为你没有改变那里的任何地址,你只是改变了指针指向的变量,所以当然取消引用指针会得到更新的值。

不,如果你重置一个unique_ptr,它会删除它拥有的指针。

你可以这样做:

int* bar = foo.release();

这导致 foo 放弃其指针的所有权并 return 它。

否,std::unique_ptr.reset 将删除现有指针。

http://www.cplusplus.com/reference/memory/unique_ptr/reset/

为了您的目的,请使用 release