简体   繁体   English

为什么不总是在C ++中通过const引用?

[英]Why not always pass by const reference in C++?

I know you pass by reference to a function in C++ when you want to change the value of the original variable. 我知道当你想要改变原始变量的值时,你会通过引用C ++中的函数来传递。 But you can also pass by reference when you want the program to be more efficient and if you don't want to change anything in the variable passed to the function, you just make it const. 但是当你希望程序更有效时你也可以通过引用传递,如果你不想改变传递给函数的变量中的任何东西,你只需要使它成为const。 My question is, why not always have your functions accept variables passed by const reference if it is more efficient than just passing the variable and having the compiler create a new one within the scope of the function? 我的问题是,为什么不总是让你的函数接受const引用传递的变量,如果它比传递变量更高效并让编译器在函数范围内创建一个新变量? To extend the question, what would be a case where a function WOULD need to copy a variable over passed through the parameters? 为了扩展这个问题,一个函数WOULD需要复制一个变量而不是通过参数?

When an argument is passed by value it is modifiable and copying it may be elided. 当一个参数按值传递时,它是可修改的,复制它可能会被省略。 For example, the canonical way to implement the assignment operator looks like this: 例如,实现赋值运算符的规范方法如下所示:

T& T::operator= (T value) {
    value.swap(*this);
    return *this;
}

At first sight it may look inefficient because a T is being copied. 乍一看,它可能看起来效率低下,因为正在复制T However, it would be copied anyway, ie, if a copy is needed one will be created either way: 但是,无论如何它都会被复制,也就是说,如果需要副本,则会以任何一种方式创建:

T& T::operator= (T const& value) {
    T(value).swap(*this); // has to do a copy right here
    return *this;
}

However, for the first version, it may be possible not to create copy at all, for example 但是,对于第一个版本,例如,可能根本不创建副本

T f() { return T(); }
// ...
T x = ...;
x = f();

When assigning the result of f() which is of type T to x the compiler may decide that it doesn't need to copy the result of f() and instead pass it into the assignment operator directly. 当将类型为Tf()的结果赋值给x ,编译器可能会认为它不需要复制f()的结果,而是直接将它传递给赋值运算符。 In that case, if the assignment operator takes the argument by const& the compiler has to create a copy inside the assignment operator. 在这种情况下,如果赋值运算符通过const&获取参数,则编译器必须在赋值运算符内创建副本。 In the implementation taking the argument by value it can elide the copy! 在按值实现参数的实现中,它可以忽略副本! In fact, the return from f() can already elide the copy, ie, the call to f() and the following assignment may just involve the default construction of the object! 实际上,从f()返回可能已经忽略了副本,即对f()的调用,以下的赋值可能只涉及对象的默认构造! ... and for many modern compilers that is, indeed, the case! ......对于许多现代编译器而言确实如此!

Put differently: if you need to copy an argument, getting it passed by value may avoid the need to create a copy. 换句话说:如果您需要复制参数,通过值传递它可以避免创建副本的需要。 Also, you can std::move() from value arguments but not from const& arguments. 此外,您可以从值参数std::move()而不是const& arguments。

But you can also pass by reference when you want the program to be more efficient and if you don't want to change anything in the variable passed to the function, you just make it const. 但是当你希望程序更有效时你也可以通过引用传递,如果你不想改变传递给函数的变量中的任何东西,你只需要使它成为const。

It's wrong. 这是不对的。 Passing the arguments of basic types (int, float, char....) is more effecient than passing them by reference. 传递基本类型(int,float,char ....)的参数比通过引用传递它们更有效。 const & is more effecient in passing the BIG OBJECT. const&更有效地传递了BIG OBJECT。 Because the reference is a alias of a object in essential, the compiler need to handle more information. 因为引用是必要的对象的别名,所以编译器需要处理更多信息。

References are essentially a special contract over pointers the payback for which is some syntactic sugar and simplicity. 参考文献本质上是一个特殊的合约,其指标是回报,其中包括一些语法糖和简单性。 Within a function body, the compiler may be at liberty to eliminate references, but when they are passed as arguments what actually gets passed is a pointer. 在函数体中,编译器可以自由地消除引用,但是当它们作为参数传递时,实际传递的是指针。

The upshot is that using a reference may incur derference costs. 结果是使用参考可能会产生差异成本。

void func(int& i) {
    int j = i; // secretly a dereference
    // ...
}

incurs the same overheads as 招致同样的开销

void func(int* i) {
    int j = *i;
    // ...
}

Local, convenience references can often be optimized out, but reference arguments have to be dereferenced at least the first time they are used. 通常可以优化本地便利引用,但至少在第一次使用它们时必须取消引用引用参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM