C++;:如何决定是按ref还是按值传递参数? < C++ >我如何决定我应该通过值或引用/指针传递一个参数?(告诉我32位和64位的答案)让我们拿A来说。作为指向32位值的指针,2个32位值是多还是少

C++;:如何决定是按ref还是按值传递参数? < C++ >我如何决定我应该通过值或引用/指针传递一个参数?(告诉我32位和64位的答案)让我们拿A来说。作为指向32位值的指针,2个32位值是多还是少,c++,performance,struct,pass-by-reference,pass-by-value,C++,Performance,Struct,Pass By Reference,Pass By Value,B对我来说,似乎我总是应该忽略价值。我认为我应该通过值传递,但有人告诉我(但我没有看到证据)处理器不处理值,而不是它们的位大小,所以这需要更多的工作。所以,如果我将它们传递给其他人,那么按值传递会更费力吗?这样byref会更快吗?最后我加入了一个枚举。我认为枚举应该始终按值进行 注意:当我说by ref时,我指的是常量引用或指针(不能忘记常量…) 现在告诉我答案,如果我多次按下参数,代码不使用尾部调用?(假设只有4次左右的调用才能使用这些值)很大程度上取决于您的需求,但最佳做法是通过引用传递,因

B对我来说,似乎我总是应该忽略价值。我认为我应该通过值传递,但有人告诉我(但我没有看到证据)处理器不处理值,而不是它们的位大小,所以这需要更多的工作。所以,如果我将它们传递给其他人,那么按值传递会更费力吗?这样byref会更快吗?最后我加入了一个枚举。我认为枚举应该始终按值进行

注意:当我说by ref时,我指的是常量引用或指针(不能忘记常量…)


现在告诉我答案,如果我多次按下参数,代码不使用尾部调用?(假设只有4次左右的调用才能使用这些值)

很大程度上取决于您的需求,但最佳做法是通过引用传递,因为这样可以减少内存足迹

如果您按值传递大型对象,则会在内存中创建该对象的副本,并调用复制构造函数来创建该对象的副本

因此需要更多的机器周期,而且,如果按值传递,更改不会反映在原始对象中

所以试着通过引用传递它们

希望这对你有所帮助


尊敬的Ken,我对你的完整问题有点不清楚,但我可以回答你什么时候使用按值传递或按引用传递

当通过值传递时,您将参数的完整副本保存到调用堆栈中。这就像是在函数调用中创建一个局部变量,用传入的任何内容初始化

当通过引用传递时,您。。。嗯,通过参考传递。主要区别在于可以修改外部对象

对于通过引用传递的大型对象,可以减少内存负载。对于基本数据类型(例如32位或64位整数),性能可以忽略不计


一般来说,如果你要在C/C++中工作,你应该学会使用指针。作为参数传递对象几乎总是通过指针(vs引用)传递。您绝对必须使用引用的少数实例位于复制构造函数中。您也希望在操作符中使用它,但这不是必需的。

忘记堆栈大小。如果要更改引用,应按引用传递,否则应按值传递

防止由于允许函数意外更改数据而引入的bug比浪费几个字节的堆栈空间要重要得多

如果堆栈空间成为问题,请停止使用太多级别(例如用迭代解决方案替换递归解决方案)或扩展堆栈。四级递归通常不是那么繁重,除非您的结构非常庞大或者您在嵌入式世界中操作

如果性能出现问题,请找到一个更快的算法:-)如果不可能,那么您可以考虑按引用传递,但您需要了解,它正在破坏调用方和被调用方之间的契约。如果你能接受,没关系。我一般不能:-)


值/引用二分法的目的是控制在语言级别作为参数传递的对象发生了什么,而不是摆弄语言实现的工作方式。

按值复制对象通常是一个坏主意-需要更多的CPU来执行构造函数功能;为实际对象提供更多内存。使用
const
防止函数修改对象。函数签名应该告诉调用方引用对象可能发生的情况

int
char
指针
这样的东西通常是按值传递的

至于您概述的结构,传递值实际上并不重要。您需要进行分析才能找到答案,但在程序的总体方案中,您最好在其他地方寻找提高CPU和/或内存性能的方法。

为了一致性,我通过引用传递所有参数,包括内置参数(当然,在可能的情况下使用
const

我确实在性能关键的领域中测试了这一点——与内置设备相比,最糟糕的情况是损失微乎其微。对于非内置的,当调用很深时(作为泛化),引用可以快很多。这对我来说很重要,因为我正在做相当多的深度TMP,其中函数体很小

你可以考虑打破这个惯例,如果你在计算指令,硬件是登记饿死(例如嵌入式),或者如果函数不是内联的好候选。< /P>


不幸的是,您提出的问题比表面上看起来更复杂——答案可能因您的平台、ABI、调用约定、寄存器计数等的不同而有很大差异。

首先,引用和指针不一样

通过指针 通过指针传递参数(如果有/部分适用):

  • 传递的元素可以为null
  • 资源是在被调用函数内分配的,调用方负责释放此类资源。在本例中,请记住为该资源提供一个free()函数
  • 该值为变量类型,例如
    void*
    。当它的类型在运行时确定或取决于使用模式(或隐藏实现,即Win32句柄),例如线程过程参数。(这里有利于C++模板和STD::For),并且仅在环境不允许的情况下使用指针来实现。
  • 参照 通过引用传递参数(如果其中任何/某些参数适用):

  • 大部分时间。(更喜欢通过常量引用传递)
  • 如果希望调用方可以看到对传递参数的修改。(除非使用const引用)
  • 如果传递的参数从不为null
  • 如果你知道什么是
    struct A { int a, b; }
    struct B { int a; }
    struct C { char a, b; }
    enum D   { a,b,c }
    void fn(T a);