【发布时间】:2019-09-27 19:31:52
【问题描述】:
我刚开始学习新的 C++ 内存模型:
#include <string>
#include <iostream>
#include <memory>
void print(unique_ptr<std::string> s) {
std::cout << *s << " " << s->size() << "\n";
}
int main() {
auto s = std::make_unique<std::string>("Hello");
print(std::move(s));
std::cout << *s;
return 0;
}
现在调用cout << *s; 会导致段错误,这是应该的。我明白为什么会这样。但我也想知道是否有办法取回所有权。我希望能够在将值传递给函数后使用它。
【问题讨论】:
-
如果你
std::move它,那么你就是在放弃它。如果您想保留它,请不要使用std::move。通过引用传递。 -
^ 话虽如此,即使您决定转让
s的所有权,std::move也可能不是最好的方法。看看文档中unique_ptr的方法 -
没有“应该导致段错误”的代码。像这样的不正确代码被描述为具有未定义的行为,这意味着标准不保证一个体面的编译器应该做什么。所以它可能会打印“(null)”,可能什么都不做,可能会给你鼻守护进程。 (也许一旦您开始将目光从标准转向特定的编译器和架构,但随后您会大量依赖于优化选择,而这些选择经常会发生变化。)
-
a)
unique_ptr<string>作为参数的意思是:我会把这个字符串转给你。作为函数的参数,这几乎不是您想要的。你不应该使用unique_ptr作为参数,除非真的需要。 b) 使用引用,如果您不修改它,则使用 const 引用。const string&的意思是:我会给你一个存在的字符串(引用不能为空,不需要空检查)它是我的(所有权仍然在调用者身上) 并且您不应该修改它。string&表示:它是我的,但你可以触摸。 c) 可以为空的标准指针(即可选参数)。 -
@aschepler 特定平台 (POSIX) 确实定义了导致段错误的某些事情。 (虽然我实际上并没有检查过 POSIX 标准)
标签: c++ unique-ptr