为什么不总是在C++中传递常量引用
Why not always pass by const reference in C++?
我知道当您要更改原始变量的值时,您会通过引用C++中的函数来传递。 但是,当您希望程序更高效时,您也可以通过引用传递,如果您不想更改传递给函数的变量中的任何内容,只需将其设置为const即可。我的问题是,如果它比仅仅传递变量并让编译器在函数范围内创建一个新变量更有效,为什么不总是让你的函数接受通过 const 引用传递的变量?为了扩展问题,函数需要复制变量超过通过参数的情况是什么?
当参数按值传递时,它是可修改的,复制它可能会被省略。例如,实现赋值运算符的规范方法如下所示:
T& T::operator= (T value) {
value.swap(*this);
return *this;
}
乍一看,它可能看起来效率低下,因为正在复制T
。但是,无论如何它都会被复制,即,如果需要副本,将以任何一种方式创建一个副本:
T& T::operator= (T const& value) {
T(value).swap(*this); // has to do a copy right here
return *this;
}
但是,对于第一个版本,可能根本不创建副本,例如
T f() { return T(); }
// ...
T x = ...;
x = f();
当分配 f()
x
T
的结果时,编译器可能会决定它不需要复制 f()
的结果,而是直接将其传递给赋值运算符。在这种情况下,如果赋值运算符通过const&
获取参数,则编译器必须在赋值运算符内创建副本。在按值获取参数的实现中,它可以省略副本!事实上,从 f()
返回已经可以省略副本,即对 f()
的调用和随后的赋值可能只涉及对象的默认构造!...对于许多现代编译器来说,情况确实如此!
换句话说:如果你需要复制一个参数,通过值传递它可以避免创建副本的需要。此外,您可以从值参数std::move()
,但不能从const&
参数中。
但是,当您希望程序 更高效,如果您不想更改 变量传递给函数,你只需让它成为常量。
错了。传递基本类型(int、float、char...)的参数比通过引用传递它们更有效。const & 在传递 BIG OBJECT 时更有效率。由于引用本质上是对象的别名,因此编译器需要处理更多信息。
引用本质上是一种特殊的指针契约,其回报是一些语法糖和简单性。在函数体中,编译器可以自由地消除引用,但是当它们作为参数传递时,实际传递的是一个指针。
结果是使用引用可能会产生引用成本。
void func(int& i) {
int j = i; // secretly a dereference
// ...
}
产生与 相同的开销
void func(int* i) {
int j = *i;
// ...
}
本地、方便的引用通常可以优化出来,但引用参数必须至少在第一次使用时取消引用。
- 什么时候在C++中返回常量引用是个好主意
- 通过常量引用传递参数的矩阵模板类
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么常量方法可以采用非常量引用?
- 为什么当我们有常量引用时创建临时对象?
- 如何返回向量的常量引用?
- C++:常量引用参数
- 不同于按值传递和常量引用传递的程序集
- 为什么const_cast和static_cast常量引用没有效果?
- C++ 获取函数在常量引用中按值返回的结果
- 从 BubbleSort* 类型的右值初始化 'AssortedSorter&' 类型的非常量引用无效"
- C++ 在类中使用常量引用文本时 O2 内存泄漏
- 是否可以跨 dll 边界返回常量引用/指向 std::vectors?
- C++中大多数/所有 setter 函数的参数是否应该写为常量引用?
- 通过非常量引用参数修改常量引用参数
- 将常量引用传递给线程
- 为什么C++中没有常量引用,就像常量指针一样?