通过const引用将参数传递给非void函数:它被视为副作用吗?

时间:2016-02-08 19:40:33

标签: c++ function parameter-passing

编写函数(不是过程)最简洁的方法是什么?

第二种解决方案是否被告知有“副作用”?

struct myArea
{
  int t[10][10]; // it could by 100x100...
};

解决方案1:按值传递

 double mySum1(myArea a)
 {
   // compute and return the sum of elements
 }

解决方案2:通过const引用

double mySum2(const myArea & a)
{
  // compute and return the sum of elements
}

我喜欢的是第一个(清洁功能),尽管效果较差。但是当需要复制大量数据时,这可能非常耗时。

感谢您的反馈。

3 个答案:

答案 0 :(得分:2)

我的术语有很多狡辩:

  1. 没有"程序"在C或C ++中。最多,有些函数不返回任何值:"void"

  2. 您的示例没有"side effect"

  3. 我不确定你的意思"清洁功能" ...但我 HOPE 你不是说"更少的来源==更清洁的代码"。事实并非如此:(

  4. 回答您的原始问题:

    1. 在您的示例中,This application has no explicit mapping for /error, so you are seeing this as a fallback. Mon Feb 08 16:10:47 EST 2016 There was an unexpected error (type=Internal Server Error, status=500). Circular view path [stuff123456789]: would dispatch back to the current handler URL [/site/stuff123456789] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.) 会导致 COMPLETELY UNNECESSARY COPY 的空间和CPU开销。不要这样做:)

    2. 在我看来,double mySum1(myArea a)double mySum1(myArea & a)是等价的。就个人而言,我更喜欢double mySum1(myArea * a) ...但大多数C ++开发人员(正确!)更喜欢double mySum1(myArea * a)

    3. double mySum1(myArea & a)是最好的:它具有2)的运行时效率,并且它表明你 WON' T 修改数组的意图。

    4. PS: 我从以下测试生成了汇编输出:

      double mySum1 (const myArea & a)

      mySum1,正如您所期望的那样,有额外的代码来执行额外的复制。

      然而,mySum2,mySum3和mySun4的输出是 IDENTICAL

      struct myArea {
        int t[10][10];
      };
      
      double mySum1(myArea a) {
        double sum = 0.0;
        for (int i=0; i < 10; i++)
          for (int j=0; j<10; j++)
            sum += a.t[i][j];
        return sum;
      }
      
      double mySum2(myArea & a) {
        double sum = 0.0;
        for (int i=0; i < 10; i++)
          for (int j=0; j<10; j++)
            sum += a.t[i][j];
        return sum;
      }
      
      double mySum3(myArea * a) {
        double sum = 0.0;
        for (int i=0; i < 10; i++)
          for (int j=0; j<10; j++)
            sum += a->t[i][j];
        return sum;
      }
      
      double mySum4(const myArea & a) {
        double sum = 0.0;
        for (int i=0; i < 10; i++)
          for (int j=0; j<10; j++)
            sum += a.t[i][j];
        return sum;
      }
      

      还值得注意的是&#34; const&#34;是它可以帮助编译器尽可能地执行几种不同类型的优化。例如:

答案 1 :(得分:1)

请注意,没有&#34;程序&#34;在C ++中。不返回任何内容的函数仍然是函数。

现在问题:如果您的参数是输出参数或输入/输出参数,也就是说,您希望调用者看到函数内部对传递给它的对象所做的更改,然后通过引用传递。否则,如果要复制的类型很小/非常便宜,则按值传递。否则,通过引用传递给const。在你的情况下,我通过引用传递给const。

答案 2 :(得分:1)

参数传递本身不是副作用。

如果一个函数做了任何不可观察的事情而不仅仅返回一个值,那将是一个副作用。
(例如,修改参考参数,打印某些内容,修改任何全局状态......)

即使您通过非const引用,副作用的存在取决于您是否修改引用的对象。