【问题标题】:C++. Return an object or pass a reference to be filled?C++。返回一个对象或传递一个要填充的引用?
【发布时间】:2017-05-04 06:37:46
【问题描述】:

你好。我寻找答案,但没有找到这个特定问题的答案。 Here 我找到了article,它展示了 Visual C++ 编译器如何在各种情况下消除冗余的 Copy 构造函数和 Destructor 调用。我相信 Clang 和 GCC 也是如此。

有两个结构体:输入数据Waveform 和结果Analyzed。两个函数做同样的工作,但以不同的方式返回结果。第一个创建一个本地 Analyzed 并返回它(副本),第二个引用一个已经创建的对象来填充它,返回相同的。

struct Waveform;
struct Analyzed;

Analyzed  analyze( Waveform const& wf );  // Form 1
Analyzed& analyze( Waveform const& wf, Analyzed& an );  // Form 2

示例用法,假设Waveform wf 已经在范围内:

auto an0 = analyze(wf);
Analyzed const& an1 = analyze(wf);

Analyzed an3;
analyze(wf,an3);

对我来说Form 1更短更方便。

据我所知,在C 中,一个好的做法是考虑将函数指针传递给预分配的内存(因此用户负责内存),而不是返回大于sizeof(int) 的对象,而是返回指针或错误号.

问题。analyze() 形式之一更好吗?为什么?
是否存在任何性能问题、额外副本、陷阱?
有什么特殊情况吗?


我也可以想象Form 1如何重用Form 2

Analyzed  analyze( Waveform const& wf ){
  Analyzed an;
  analyze(wf,an);
  return an;
}

更长的描述。 有两个结构体:Waveform 代表一个信号,Analyzed - 信号的特征。

struct Waveform {
  size_t len;
  float *arr;
  float sampleRate;
  //...
}

struct Analyzed {
  struct Entry { size_t idx; float value; };
  Entry max;
  Entry min;
  float peakToPeak;
  float mean;
  //...
};

Analyzed  analyze( Waveform const& wf );
Analyzed& analyze( Waveform const& wf, Analyzed& an );

【问题讨论】:

  • 这与C标签无关。
  • @SouravGhosh 我添加了 C 标记,因为“......在 C 中一个很好的做法考虑通过......”
  • 没关系,但恕我直言,标签不属于这里。\
  • 有很多语言,每种语言都有自己的最佳实践。没有理由单独列出 C。

标签: c++ reference return return-value


【解决方案1】:

现在很多人都喜欢这种形式:

auto a = analyze(wf);

写起来简单易懂;什么都不会出错。 C++17 草案规范包括保证不涉及中间临时对象; C ++ 14 使它成为可选的。大多数编译器确实接受了这个选项。

如果您将其与以下内容进行比较:

Analyzed an;
analyze(wf, an);

两个主要区别是:

  • 仅通过阅读代码并不清楚函数参数是“in”、“out”还是“in-out”参数。您必须查阅文档。
  • 如果Analyzed 没有默认构造函数,这将根本不起作用。这并不少见;让构造函数设置对象遵循良好的面向对象原则;而不是让构造函数创建一个稍后将“初始化”的虚拟外壳。

这两者都使代码更不容易理解,并且更容易出现与之相关的编码错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-19
    • 2010-12-03
    • 2013-04-28
    • 1970-01-01
    • 2015-09-15
    • 2013-08-23
    • 1970-01-01
    相关资源
    最近更新 更多