std :: unique_ptr的唯一性

时间:2014-05-18 00:56:30

标签: c++11 unique-ptr

我一直在研究std :: unique_ptr,但在某些方面对它的语义感到困惑。来自documentation

No two unique_ptr instances can manage the same object

但是,即使很难,这很可能是一个愚蠢的例子,考虑这样的代码。

std::unique_ptr<int> a(new int(10));
std::unique_ptr<int> b = std::unique_ptr<int>(a.get());
std::cout << *b << std::endl;
*a = 5;
std::cout << *b;

a和b在这里管理同一个对象,输出是10 5.当然我在调试模式结束时得到一个断言失败错误,因为两个独特的ptrs试图在结束时破坏相同的对象范围。

我知道这很愚蠢,不建议使用这种用法,但是当它不是很明显(一个类成员调用另一个等等)时我遇到了这个问题,并且断言失败是我开始的事情。

我的问题是上面的句子究竟意味着什么:它是由标准构成的,一个体面的编译器不应该允许你这样做(我在vs2013 btw上)或者你必须这样做(永远不要让两个unique_ptrs指向同一个对象)(不太可能,因为unique_ptrs的目的是让我们不那么担心我的想法。)或者当涉及a.get()时,我永远不应该使用关于原始指针(unique_ptr)的任何内容。

1 个答案:

答案 0 :(得分:2)

你的最后一句话是对的。一旦你使用a.get()的原始指针,如下面一行所示,你已经抛弃了std::unique_ptr给你的所有承诺。

std::unique_ptr<int> b = std::unique_ptr<int>(a.get());

在转换为原始指针时保留唯一性的正确语义是使用a.release()

std::unique_ptr<int> b = std::unique_ptr<int>(a.release());

当然,如果您在两个std::move实例之间移动所有权,通常只需使用std::unique_pointer进行分配或初始化,如documentation所示。下面两行中的任何一行都应该有效。

std::unique_ptr<int> b(std::move(a));
std::unique_ptr<int> b = std::move(a);

为了使std::move语义更清晰,请考虑以下测试程序。

#include <stdio.h>
#include <memory>
#include <stdlib.h>


int main(){
    std::unique_ptr<int> a(new int(10));
    printf("%p\n", a.get());
    std::unique_ptr<int> b(std::move(a));
    printf("%p\n", a.get());
    printf("%p\n", b.get());
}

在我的系统上,输出如下。观察第一行和最后一行匹配。

0x1827010
(nil)
0x1827010