草庐IT

c++ - C++11 move 语义是在做一些新的事情,还是只是让语义更清晰?

coder 2023-05-03 原文

我基本上是想弄清楚,整个“move 语义”概念是全新的,还是只是让现有代码更易于实现?我总是对减少调用复制/构造函数的次数感兴趣,但我通常使用引用(可能还有 const)传递对象,并确保我总是使用初始化列表。考虑到这一点(并查看了整个丑陋的 && 语法),我想知道是否值得采用这些原则或像我已经做的那样简单地编码?这里有什么新东西吗,还是我已经做的只是“更简单”的语法糖?

最佳答案

TL;DR

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

长答案:为什么它是新的以及一些可能不明显的含义

move 语义正如其名称所暗示的那样——即一种显式声明用于 move 对象而不是复制的指令的方法。除了明显的效率优势之外,这还为程序员提供了一种符合标准的方法来获得可 move 但不可复制的对象。可 move 且不可复制的对象通过标准语言语义传达了非常清晰的资源所有权边界。这在过去是可能的,但没有标准/统一(或与 STL 兼容)的方式来做到这一点。

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

move 语义特别有趣,因为它非常适合 RAII 习语,这是 C++ 最佳实践的长期基石。 RAII 不仅仅包含这个例子,但我的观点是, move 语义现在是一种标准的方式来简洁地表达(除其他外)可 move 但不可复制的对象。

您不必总是明确定义此功能以防止复制。一种称为“复制省略”的编译器功能会从按值传递的函数中消除大量不必要的拷贝。

关于 RAII 的犯罪不完整速成类(class)(面向初学者)

我知道您并没有要求提供代码示例,但这里有一个非常简单的示例,可能会对可能不太熟悉该主题或 Move Semantics 与 RAII 实践相关性的 future 读者有所帮助。 (如果您已经理解这一点,请跳过此答案的其余部分)

// 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 容器兼容)之外,任何熟悉此标准实践的程序员都会立即认识到您的意图

关于c++ - C++11 move 语义是在做一些新的事情,还是只是让语义更清晰?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16823615/

有关c++ - C++11 move 语义是在做一些新的事情,还是只是让语义更清晰?的更多相关文章

  1. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  4. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  5. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby - 找一些句子 - 2

    我想找到在某些文本中找到一些(让它是两个)句子的好方法。什么会更好-使用正则表达式或拆分方法?你的想法?应JeremyStein的要求-有一些例子示例:输入:ThefirstthingtodoistocreatetheCommentmodel.We’llcreatethisinthenormalway,butwithonesmalldifference.IfwewerejustcreatingcommentsforanArticlewe’dhaveanintegerfieldcalledarticle_idinthemodeltostoretheforeignkey,butinthis

  10. ruby - 需要重构为新的 Ruby 1.9 哈希语法 - 2

    这个问题在这里已经有了答案:HashsyntaxinRuby[duplicate](1个回答)关闭5年前。我有一个Recipe,其中包含以下未通过lint测试的代码:service'apache'dosupports:status=>true,:restart=>true,:reload=>trueend失败并出现错误:UsethenewRuby1.9hashsyntax.supports:status=>true,:restart=>true,:reload=>true不确定新语法是什么样的...有人可以帮忙吗?

随机推荐