简体   繁体   中英

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. 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. 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? To extend the question, what would be a case where a function WOULD need to copy a variable over passed through the parameters?

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. 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. In that case, if the assignment operator takes the argument by const& the compiler has to create a copy inside the assignment operator. 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! ... 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.

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.

It's wrong. Passing the arguments of basic types (int, float, char....) is more effecient than passing them by reference. const & is more effecient in passing the 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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