开发者

pass by reference c++

My teacher in c++ told me that call by reference should only be used if I'm not going to change anything on the arrays inside the function. I have some really big vectors that I'm passing around in my program. All the vectors will be modified inside the functions. My matrices are of siz开发者_运维问答es about [256*256][256][50]...

Is there some particular reason not to use call-by reference here?

AFAIK call by reference should be way faster and consume less memory?


Besides all common discussions on when and how to pass by possibly const reference for non-primitive types, arrays are quite special here.

Due to backwards compatibility with C, and there due to your specific problem: arrays can be huge, arrays are never really passed by value in either C or C++. The array will decay into a pointer to the first element, so when you write:

void foo( type array[100] );

The compiler is actually processing:

void foo( type *array );

Regardless of what the size of the array is (two common pitfalls there: trusting that array is an array inside foo and believing that it will be guaranteed to be 100 elements on it.

Now, in C++ you can actually pass arrays by reference, but the reference must be of the concrete type of the array, that includes the size:

void foo_array( type (&array)[100] );

The funny syntax there is telling the compiler that the function will take an array of exactly 100 elements of type type. The advantage there is that the compiler can perform size checking for you:

// assuming 'type' is defined
int main() {
   type array0[99];
   type array1[100];

   foo( array0 );     // compiles, but if size=100 is assumed it will probably break
                      // equivalent to: foo( &array0[0] )
   // foo2( array0 ); // will not compile, size is not 100
   foo2( array1 );    // compiles, size is guaranteed to be 100
}

Now, the problem is that your function will only work for an array of exactly 100 elements, and in some cases, you might want to perform the same operation in different array sizes. The two solutions are: template the function in the size of the array which will provide a size-safe implementation for each used size --greater compile time and binary size, the template is compiled for every different size-- or using the pass-by-value syntax, which will make the array decay --not safe in size, that must be passed as extra argument, lesser compile time and binary size. A third option is combining both:

void foo( type *array, int size );
template <size_t N>
void foo( type (&array)[N] ) {
   foo( array, N );
}

In this case, while there will be one templated foo for each size, the compiler will most probably inline the call and the generated code would be equivalent to the caller providing the array and size. No extra computations needed and type safety for real arrays.

Now, pass-by-reference is very rarely used with arrays.


My teacher in c++ told me that call by reference should only be used if I'm not going to change anything on the arrays inside the function.

It should be used when you are not changing something inside the function or you change things and want the changes to be reflected to the original array or don't care about the changes to be reflected in the original array.

It shouldn't be used if you don't want your function to change your original array (you need to preserve the original values after the call) and the callee function changes the values of the passed argument.


Your teacher is wrong. If you need to modify arrays, pass by reference is the way to go. If you don't want something modified, pass by const reference.


To prevent accidental changes, use pass-by-const-reference; that way, by default*, the passed-in array can't get changed by the called function.

* Can be overridden with const_cast.


You can pass by reference if:

  1. you won't modify passed object
  2. you want to modify object and don't want to keep old object untouched

When you pass something by reference, then only pointer is passed to function. If you pass whole object then you need to copy it, so it will consume more cpu and memory.


Generally speaking, objects should always be passed by reference. Otherwise a copy of the object will be generated and if the object is substantially big, this will affect performance.

Now if the method or function you are calling does not modify the object, it is a good idea to declare the function as follows:

void some_function(const some_object& o);

This will generate a compile error if you attempt to modify the object's state inside the function body.

Also it should be noted that arrays are always passed by reference.


Hold on a second.. I'm scared at how people are answering this one. Arrays, as far as I remember, are always passed by reference.

void function(int array[])
{
    std::cout << array[0] << '\n';
}

// somewhere else..
int array[2] = { 1, 2 };
function(array); // No copy happens here; it is passed by reference

Further, you can't say the array argument is a reference explicitly, as that would be the syntax for creating an array of references (something that's not allowed).

void function(int &array[]) // error here
{ /* ... */ }

So what do you mean?

Further, many are saying that you should only do that if you modify the contents of the array inside the function. Then, what about reference-to-const?

void function(const int arr[])
{
    std::cout << arr[0] << '\n';
}

-- edit

Will somebody please point me out how to not pass an array by reference in C++?

-- edit

Oh, so you're talking about vectors. Okay, then the rules of thumb are:

  • Pass by reference only when you want to modify the contents of the vector.
  • Pass by reference-to-const whenever you can.
  • Pass by value only when the object in question is really, really small (like a struct containing an integer, for example), or when it makes sense to (can't think of a case out of the top of my head).

Did I miss something?

-- edit

  • In the case of plain C arrays, it's a good idea to pass them by reference (like in void function(int (&array)[100])) when you want to ensure that the array has a given definite size.

Thanks, dribeas.


Usually, in introductory courses, they tell you that so you don't accidentally change something you didn't want to.

Like if you passed in userName by reference, and accidentally changed it to mrsbuxley that probably would cause errors, or at the very least be confusing later on.


I don't see any reason why you can't pass by reference. Alternatively you could pass pointers around, but I think pass by reference is better sometimes as it avoids null pointer exceptions.

If your teacher has suggested this as some kind of convention, then feel free to break it if it makes sense to. You can always document this in a comment above the function.


Our house style is to NEVER pass an object by value but to always pass a reference or const reference. Not only do we have data structures that can contain 100s of MB of data and pass by value would be an application killer, but also if we were passing 3D points and vectors by value the our applications would grind to a halt.


It is always a good choice to pass object by reference but we need to be careful and first we have to decide what is our purpose/ purpose of our function?

You have to make a choice here, whether we are gonna only read the data of an object or modify it.

Suppose you got an interface like

void increament_value(int& a);

so in this you can modify value an object which we are passing, but it is a disaster when you passing your sensitive data, you might lose you original data and can not revert it, right?

so c++ provides you a functionality to not to change the value of an object whose reference you are passing to a function, and it is always a good choice to pass a const reference of an object for e.g.,

double get_discounted_amount(const double &amount,double discount){
    return (amount*discount/100);
}

This guarantees that your actual value of an object is not gonna change, but again it depends on purpose of your interface whether you wanna change it or only use(read) it

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜