2014-05-18 91 views
2

我一直在研究std :: unique_ptr,但在某些时候对它的语义感到困惑。从documentationstd :: unique_ptr的唯一性

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.当然,我在调试模式得到一个断言失败错误在最后由于两个独特的师生比试图销毁同一对象在范围的最后。

我知道这很愚蠢,并不建议这样使用,但是当它不是很明显的时候我会遇到这种情况(一个类的成员调用另一个类等),而断言失败是我开始使用的。

我的问题是上述语句的意思:它是由标准和一个体面的编译器构成的,它不应该允许你这样做(我在vs2013 btw上)或者你必须这样做(永远不会导致两个unique_ptrs点)(不太可能,因为unique_ptrs的目的是为了让我们不那么担心。)或者当涉及unique_ptr时,我不应该使用任何关于原始指针(a.get())的东西。

回答

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转让或initializatoin如果两个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 
+0

您需要使用'std :: unique_ptr b = std :: move(a);'。您必须对'std :: unique_ptr'使用移动赋值。 – ECrownofFire

+0

@ECrownofFire,修复,谢谢...我应该检查。 – merlin2011

+0

我很难理解move semantcis。据我所知,这条线会使b指向a所指向的任何东西,并指向null,对吗? – bahti