返回值优化和私有副本构造函数 [英] Return Value Optimization and private copy constructors

查看:133
本文介绍了返回值优化和私有副本构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个简单的链表,因为最近一次面试编程挑战向我展示了我的C ++生锈了多少。在我的列表中,我声明了一个私有副本构造函数,因为我想明确避免制作任何副本(当然,惰性)。我遇到了一些麻烦,当我想通过值返回一个拥有我的列表的对象。

I've written a simple linked list because a recent interview programming challenge showed me how rusty my C++ has gotten. On my list I declared a private copy constructor because I wanted to explicitly avoid making any copies (and of course, laziness). I ran in to some trouble when I wanted to return an object by value that owns one of my lists.

class Foo
{
   MyList<int> list;  // MyList has private copy constructor

   public:
      Foo() {};
};

class Bar
{
   public:
      Bar() {};

      Foo getFoo()
      {
         return Foo();
      }
};

我得到一个编译器错误,说MyList有一个私人复制构造函数,当我尝试返回一个Foo对象按值。应该返回值优化否定任何复制的需要吗?我需要写一个复制构造函数吗?我从来没有听说过移动构造函数,直到我开始寻找这个问题的解决方案,是最好的解决方案吗?如果是这样,我必须阅读他们。如果没有,解决这个问题的首选方法是什么?

I get a compiler error saying that MyList has a private copy constructor when I try to return a Foo object by value. Should Return-Value-Optimization negate the need for any copying? Am I required to write a copy constructor? I'd never heard of move constructors until I started looking for solutions to this problem, is that the best solution? If so, I'll have to read up on them. If not, what is the preferred way to solve this problem?

推荐答案

基本问题是返回值 复制。标准在应用复制限制时不要求C ++实现。这就是为什么对象仍然必须是可复制的:所以实现的决定什么时候使用它不影响代码是否形式良好。

The basic problem is that return by value might copy. The C++ implementation is not required by the standard to apply copy-elision where it does apply. That's why the object still has to be copyable: so that the implementation's decision when to use it doesn't affect whether the code is well-formed.

无论如何,它doesn不一定适用于用户可能喜欢的每个副本。例如,没有精确的副本分配。

Anyway, it doesn't necessarily apply to every copy that the user might like it to. For example there is no elision of copy assignment.

我认为您的选项是:


  • 实施正确的副本。如果有人因为复制而导致程序缓慢,那么他们的分析器会告诉他们,如果你不想要,你不必把它作为阻止他们的工作。

  • 实施正确的移动,但没有副本(仅限C ++ 11)。

  • 更改 getFoo c> Foo& (或可能 Foo * )参数,并避免通过某种方式改变其对象的副本。一个高效的 swap 会派上用场。如果在你的例子中 getFoo 真的返回一个默认构造的 Foo ,这是相当毫无意义的,因为调用者需要构造在它们调用 getFoo 之前

  • 返回动态分配的 Foo 包含在智能指针中: auto_ptr unique_ptr 。定义为创建对象并将唯一所有权转让给其调用者的函数不应返回 shared_ptr ,因为它没有 函数。

  • 提供一个复制构造函数,但如果它曾被使用,它会以某种方式(无法链接,中止,抛出异常)。这个问题是(1)它注定失败,但编译器没有说,(2)你正在执行的质量,所以你的类不工作,如果有人故意禁用RVO由于任何原因。

  • implement a proper copy. If someone ends up with a slow program due to copying it then their profiler will tell them, you don't have to make it your job to stop them if you don't want to.
  • implement a proper move, but no copy (C++11 only).
  • change getFoo to take a Foo& (or maybe Foo*) parameter, and avoid a copy by somehow mutating their object. An efficient swap would come in handy for that. This is fairly pointless if getFoo really returns a default-constructed Foo as in your example, since the caller needs to construct a Foo before they call getFoo.
  • return a dynamically-allocated Foo wrapped in a smart pointer: either auto_ptr or unique_ptr. Functions defined to create an object and transfer sole ownership to their caller should not return shared_ptr since it has no release() function.
  • provide a copy constructor but make it blow up somehow (fail to link, abort, throw an exception) if it's ever used. The problems with this are (1) it's doomed to fail but the compiler says nothing, (2) you're enforcing quality of implementation, so your class doesn't work if someone deliberately disables RVO for whatever reason.

我可能错过了一些。

这篇关于返回值优化和私有副本构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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