繁体   English   中英

使用移动构造函数与传递指针的优势是什么?

[英]What's the advantage of using move constructor vs passing a pointer?

Foo(Foo&& other) {
  this->bar = other.bar;
  other.bar = nullptr;
}

Foo(Foo* other) {
  this->bar = other->bar;
  other->bar = nullptr;
}

上面两个似乎只是在做同样的事情。 那么为什么推荐使用移动构造函数呢? 它提供了哪些优势?

使用正确的移动构造函数的原因有很多:

  1. 习俗。 考虑以下代码:

     Foo foo; Foo bar(std::move(foo));

    如果您看到该代码,您将非常清楚您要做什么:您将foo移到bar 相比之下:

     Foo foo; Foo bar(&foo);

    这是什么意思? 它是否存储指向另一个Foo的指针? Foo是某种链表节点类型吗? 您必须在Foo的基于指针的构造函数的文档中查找它。

  2. 您无法获得指向纯右值的指针。 Foo bar(Foo{})将(C++17 之前)创建一个临时纯右值,然后从它移入bar (移动可以在 C++17 之前省略)。 但是你不能这样做: Foo bar(&Foo{})

  3. 您可以从有意义的事物中获得自动移动。 C++17 的广义省略使许多这些自动动作消失,但仍有一些:

     Foo function() { Foo foo; //Do stuff return foo; }

    这将从foo移动而无需调用std::move 原因是foo是一个即将被销毁的局部变量。 以这种方式返回它意味着从它移动到返回值是完全合理的。

    您的方式需要明确地编写return &foo 这使得auto返回类型推导变得相当困难。 这样的函数会推导出Foo* ,这意味着您刚刚返回了一个悬空指针。 而如果你确实return foo; ,它推导出一个Foo纯右值,并自动移动(可能会被忽略)。

  4. 不需要nullptr检查。 如果您使用Foo* ,则可能有人会传递空指针。 而使用参考,则不太可能(而且他们已经调用了 UB)。

如果我们想要对现有语言结构的移动支持,我们只需使用非const引用来表示“移动”,而不是指针。 通过给它自己的语法,明确什么时候我们在移动什么东西,什么时候我们不移动。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM