C ++ 11 move语义是在做新的事情,还是只是使语义更清晰? [英] Are C++11 move semantics doing something new, or just making semantics clearer?

查看:124
本文介绍了C ++ 11 move语义是在做新的事情,还是只是使语义更清晰?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上是想弄清楚,整个移动语义"概念是全新的,还是只是使现有代码更易于实现?我一直对减少调用复制/构造函数的次数感兴趣,但是我通常使用引用(可能是const)传递对象,并确保始终使用初始化列表.考虑到这一点(并研究了整个丑陋的&& amp;语法),我想知道是否值得采用这些原理或像我已经做的那样简单地编码?在这里有什么新鲜的事情吗?或者仅仅是我已经做过的更轻松"的语法糖?

I am basically trying to figure out, is the whole "move semantics" concept something brand new, or it is just making existing code simpler to implement? I am always interested in reducing the number of times I call copy/constructors but I usually pass objects through using reference (and possibly const) and ensure I always use initialiser lists. With this in mind (and having looked at the whole ugly && syntax) I wonder if it is worth adopting these principles or simply coding as I already do? Is anything new being done here, or is it just "easier" syntactic sugar for what I already do?

推荐答案

TL; DR

这绝对是新事物,它不仅仅只是一种避免复制内存的方式.

TL;DR

This is definitely something new and it goes well beyond just being a way to avoid copying memory.

移动语义正是名称所隐含的含义,即一种显式声明用于移动对象而不是复制的指令的方法.除了明显的效率优势外,这还为程序员提供了一种符合标准的方式,使对象可以移动但不可复制.可移动且不可复制的对象通过标准语言语义传达了非常清晰的资源所有权边界.过去这是可能的,但是没有标准/统一(或与STL兼容)的方法.

Move semantics are just what the name implies--that is, a way to explicitly declare instructions for moving objects rather than copying. In addition to the obvious efficiency benefit, this also affords a programmer a standards-compliant way to have objects that are movable but not copyable. Objects that are movable and not copyable convey a very clear boundary of resource ownership via standard language semantics. This was possible in the past, but there was no standard/unified (or STL-compatible) way to do this.

这很重要,因为拥有标准和统一的语义对程序员和编译器都有利.程序员不必花时间将错误引入移动例程中,而这些错误可以由编译器可靠地生成(大多数情况下);编译器现在可以进行适当的优化,因为该标准提供了一种通知编译器何时何地执行标准移动的方法.

This is a big deal because having a standard and unified semantic benefits both programmers and compilers. Programmers don't have to spend time potentially introducing bugs into a move routine that can reliably be generated by compilers (most cases); compilers can now make appropriate optimizations because the standard provides a way to inform the compiler when and where you're doing standard moves.

移动语义特别有趣,因为它非常适合RAII习惯用法,这是C ++最佳实践的长期基石. RAII不仅包含此示例,还包含其他内容,但我的观点是,移动语义现在是简洁表达(除其他事项外)可移动但不可复制的对象的标准方法.

Move semantics is particularly interesting because it very well suits the RAII idiom, which is a long-standing a cornerstone of C++ best practice. RAII encompasses much more than just this example, but my point is that move semantics is now a standard way to concisely express (among other things) movable-but-not-copyable objects.

为了防止复制,您不必总是明确定义此功能.称为复制省略" 的编译器功能将从按值传递的函数中消除很多不必要的副本.

You don't always have to explicitly define this functionality in order to prevent copying. A compiler feature known as "copy elision" will eliminate quite a lot of unnecessary copies from functions that pass by value.

我意识到您并没有要求提供代码示例,但这是一个非常简单的示例,可能会使将来的读者受益,他们可能对该主题或移动语义与RAII实践的相关性不太熟悉. (如果您已经理解了这一点,那么请跳过此答案的其余部分)

I realize you didn't ask for a code example, but here's a really simple one that might benefit a future reader who might be less familiar with the topic or the relevance of Move Semantics to RAII practices. (If you already understand this, then skip the rest of this answer)

// non-copyable class that manages lifecycle of a resource
// note:  non-virtual destructor--probably not an appropriate candidate
//        for serving as a base class for objects handled polymorphically.
class res_t {
  using handle_t = /* whatever */;
  handle_t* handle;  // Pointer to owned resource
public:
  res_t( const res_t& src ) = delete;            // no copy constructor
  res_t& operator=( const res_t& src ) = delete; // no copy-assignment

  res_t( res_t&& src ) = default;                // Move constructor
  res_t& operator=( res_t&& src ) = default;     // Move-assignment

  res_t();                                       // Default constructor
  ~res_t();                                      // Destructor
};

此类的对象将在构造时分配/提供所需的任何资源,然后在销毁时释放/释放它.由于数据成员指向的资源绝不会意外转移到另一个对象,因此,资源的合法所有者永远不会受到质疑.除了使您的代码不易受滥用或错误(并易于与STL容器兼容)之外,熟悉此标准做法的任何程序员都可以立即识别您的意图.

Objects of this class will allocate/provision whatever resource is needed upon construction and then free/release it upon destruction. Since the resource pointed to by the data member can never accidentally be transferred to another object, the rightful owner of a resource is never in doubt. In addition to making your code less prone to abuse or errors (and easily compatible with STL containers), your intentions will be immediately recognized by any programmer familiar with this standard practice.

这篇关于C ++ 11 move语义是在做新的事情,还是只是使语义更清晰?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆