C++ 如果在函数中包含常量,则为&;冗余的

C++ 如果在函数中包含常量,则为&;冗余的,c++,C++,下面的两个函数规范是否总是编译成相同的东西?如果您使用const,我看不出是否需要副本。如果它们不一样,为什么 void(const int y); void(const int& y); 没有优化。。。这是不一样的 第一行代码获取传递到此函数的值的副本 第二行代码获取变量的引用,函数将始终直接从调用位置变量读取值 在这两种情况下,编译器(通过关键字const)被告知(在函数内部)这些变量不得修改。如果函数中有任何修改,将生成一个错误。该&指定通过引用传递对象(至少在程序集级别类似于通

下面的两个函数规范是否总是编译成相同的东西?如果您使用const,我看不出是否需要副本。如果它们不一样,为什么

void(const int y);
void(const int& y);

没有优化。。。这是不一样的

第一行代码获取传递到此函数的值的副本


第二行代码获取变量的引用,函数将始终直接从调用位置变量读取值


在这两种情况下,编译器(通过关键字const)被告知(在函数内部)这些变量不得修改。如果函数中有任何修改,将生成一个错误。

&
指定通过引用传递对象(至少在程序集级别类似于通过指针传递)。因此

现在添加
const
关键字只表示函数承诺不更改对象

void fcval(const type x)
{
  // x is a local copy of the data passed by the caller.
  // modifying x is not allowed
}
type a;
fcval(a);  // a will not be changed

void fcref(const type &x)
{
  // x is a mere reference to an object
  // changing x is not allowed
}
type b;
fcref(b);  // b will not be changed

由于副本可能很昂贵,如果不需要,应避免使用。因此,传递常量对象的方法a la
fcref
(当
fval
快速时,内置类型除外)。

不同。如果参数在传递后发生更改(例如,因为它被另一个线程更改),则第一个版本不受影响,因为它有一个副本。在第二个变量中,调用的函数可能不会更改参数本身,但会受到对
y
的更改的影响。对于线程,这可能意味着它需要一个互斥锁。

const
只是意味着函数不能修改
y
的值,但这对
y
本身是通过值(复制)还是通过引用传递没有影响。两件不同的事情。考虑当<代码> INT/COM>更改为非POD类时会发生什么。然后,按值传递和按引用传递之间的差异变得更加明显。啊,如果你有常数但不包括&,它仍然复制?是的,它仍然是本地副本,因为它是按值传递的。从技术上讲,
const int y
int y
之间也有区别,特别是在非平凡类型的情况下。例如,您不能轻易地将前者作为非常量传递,或者不能调用非常量的方法。即使是本地版本。@Swift,不是技术上的,而是非常实用的。即使是内置类型。“第二行代码获取变量的地址”这不是真的。为什么不是真的?因为它声明了一个引用参数-与获取任何对象的地址无关。什么是引用?它是一个地址(指针)。它存储在堆栈上,然后(在幕后)用于访问变量。见上面的答案。这是一个参考。一个现有对象的另一个名称。通常是在现代C++中的值。@ Sergya只在您想要修改或存储本地副本时才使用。通过值传递
std::pair
通常比通过引用传递更快。
void fcval(const type x)
{
  // x is a local copy of the data passed by the caller.
  // modifying x is not allowed
}
type a;
fcval(a);  // a will not be changed

void fcref(const type &x)
{
  // x is a mere reference to an object
  // changing x is not allowed
}
type b;
fcref(b);  // b will not be changed