Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 传递引用的开销是多少?_C++_Performance_Coding Style_Reference_Pass By Reference - Fatal编程技术网

C++ 传递引用的开销是多少?

C++ 传递引用的开销是多少?,c++,performance,coding-style,reference,pass-by-reference,C++,Performance,Coding Style,Reference,Pass By Reference,当相关getter返回引用时,访问成员变量的代价有多高 例如,如果您有一个类需要相当频繁地使用这样的访问器,那么将所述引用存储在需要使用它的类中并简单地初始化一次会有多高的效率 Get函数通常不应返回引用。这样做的原因是,它使该成员可供公众使用-如果你想这样做,只需使其成为公共成员 class foo { int bar; public: int& get_bar() { return bar; } // this is silly! Just make bar publ

当相关getter返回引用时,访问成员变量的代价有多高


例如,如果您有一个类需要相当频繁地使用这样的访问器,那么将所述引用存储在需要使用它的类中并简单地初始化一次会有多高的效率

Get函数通常不应返回引用。这样做的原因是,它使该成员可供公众使用-如果你想这样做,只需使其成为公共成员

class foo {
  int bar;
  public:
    int& get_bar() { return bar; } // this is silly! Just make bar public!
}
无论如何,如果它像
get\u bar
那么简单,它将内联到类似于
foo.bar
的东西。正如Oli所指出的,您也可以将其作为const引用,尽管对于像
int
这样的小类型,您应该继续并按值返回

对于更昂贵的类型,引用开始是有益的。你可以假设:

  • 价值的“开销”基于您返回的内容的大小
  • 引用的“开销”基于引用的大小和取消引用的成本
例如:


关于复杂性,返回或传递引用就像传递指针一样。它的开销相当于传递一个指针大小的整数,再加上一些指令。简言之,这几乎在所有情况下都是尽可能快的。小于或等于指针大小的内置类型(例如int、float)是明显的例外

在最坏的情况下,传递/返回引用可能会添加一些指令或禁用某些优化。这些损失很少超过按值返回/传递对象的成本(例如,调用复制构造函数+析构函数要高得多,即使对于非常基本的对象也是如此)。通过引用传递/返回是一个很好的默认值,除非每个指令都计数,并且您已经测量了这种差异

因此,使用引用具有难以置信的低开销


在不知道类型及其构造函数/析构函数的复杂性的情况下,无法真正量化它会快多少,但如果它不是内置类型,那么在大多数情况下,保持一个局部并通过引用返回它将是最快的-这完全取决于对象及其副本的复杂性,但是,只有极其平凡的对象才能接近引用的速度。

如果函数定义可用且相对简单,那么这样的函数是内联的,与直接访问成员相比没有任何开销。否则,操作的顺序就像从类/结构对象获取地址、应用偏移量获取成员的地址并将该地址返回给调用方一样简单。现在,对于这些情况,只有当对象不可复制或其大小大于指针大小时,才有意义通过引用返回。不可复制对象的原因是显而易见的,否则您将查看复制开销—结构的大小与指针的大小。因此,经验法则是:通过引用(或指针)返回大对象,通过复制小对象(整数、双精度等)。在那些不必通过程序控制成员访问权限的情况下,只需使用对成员具有公共访问权限的结构,不要用大量的getter和setter填充代码。

坦率地说,如果您开始怀疑这种开销:您是否已经考虑过调用约定,使用stdcall而不是cdecl


您从中获得的速度量与讨论此问题时所说的速度量相似。

如果您在一个标记为[编码风格]的问题中询问性能开销…开销与什么相比?与在类中存储引用变量并引用该变量相比。我在问题中确实说过。您可以始终返回一个
常量int&
。但更重要的一点仍然是,它将内部构件与接口相耦合。(我不打算+1这个,因为它不能回答问题…)我对此一无所知,你能详细说明一下吗?msdn上的那篇文章展示了不同的调用约定。你应该先读一读关于谷歌的书,谷歌有很多信息。但我想说的是,对这一点感到疑惑还为时过早。
foo x;
x.get_value().func(); // calls copy constructor at least once and destructor
x.get_reference().func(); // may require dereference when using