【问题标题】:When to use move semantics over references or unique pointers?何时在引用或唯一指针上使用移动语义?
【发布时间】:2020-11-03 04:54:19
【问题描述】:

我是 C++ 新手,刚刚学习移动语义。所以据我了解,使用移动构造函数我可以做类似的事情

MyObj obj1;
MyObj obj2 = std:move(obj1);

我们必须定义自己的移动构造函数来清理 obj1 等。

如果我们知道obj1obj2 使用完毕之前不会被销毁,我们似乎可以将obj2 作为对obj1 的引用。但除此之外,我们不能只使用unique_ptr 来代替吗?这样我们只需为 obj1 创建一个唯一指针,然后传递这个指针而不是尝试移动对象?

是否有一些我没有考虑的情况?

【问题讨论】:

  • @SergeyA 这就是评论的原因。我已经对其进行了编辑,OP可以查找为什么需要去掉括号。 (另一种解决方案是使用大括号:MyObj obj1{};。)
  • 我认为这个问题归结为ownership。搬家是所有权的转移。与为现有变量建立备用名称的引用非常不同。 unique_ptr 代表所有权。如果你传递一个指针,你仍然和传递一个引用在同一个世界。该对象由其他人拥有。如果您想将所有权从一个 unique_ptr 转移到另一个,您就可以重新搬家了。
  • 如果您要移动东西以防止复制,您是移动还是使用指针在很大程度上取决于对象是否可以从移动中受益。
  • @user4581301 那么在我列出的示例中是否正确地说,将obj1 包装在一个唯一的指针中,这样我就不需要显式定义移动构造函数和移动赋值我的myObj 类的运算符。但是,无论如何,我仍在使用std::move,只是在unique_ptr 对象上而不是MyObj 对象上??
  • 是的,但是“哪个更好地描述了我想要的行为?”在选择任何一个之前都应该询问。如果性能是您的主要关注点,Profile。还要问“将动态分配引入这项工作是否更昂贵?”即使移动很昂贵,移动一次也可能比永远追逐指针更便宜。如果你只是想避免编写一个可能很复杂的移动构造函数(复制和交换使移动赋值变得很容易),迟早有人会在没有指针的情况下使用代码并发现缺陷。

标签: c++ smart-pointers unique-ptr move-semantics


【解决方案1】:

根据您提供的示例,我同意您可以在此处使用参考,甚至可以使用 shared_ptr,但这实际上取决于您的用例。

但是,移动语义在表达所有权变更方面非常方便。例如,假设obj1 是一些资源(想想数据库连接、您正在编写的文件等)。现在考虑以下几点:

int func1() {
   MyObj obj1;
   // do something with obj1
   func2(std::move(obj1));
   // do some other stuff without obj1
   return 0;
}

func1 的第三行,我们将obj1 的所有权转让给func2。在这行之后,func1 不再拥有obj1 并且不应使用它,而func2 可以使用obj1 做任何需要做的事情。

这对于资源特别有用,比如文件,func1 可以对文件执行某些操作,然后让 func2 执行其他操作。通过使用std::move,它有点像func1 将不再修改此对象的合同。这可以防止func1 潜在地覆盖func2 所做的工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多