Why wouldnt you just use always values most of the time, |
For basic types like int... you should.
and if speed is needed, use references. |
References are not necessarily faster. In fact passing a basic type like an int by reference may be slower than passing it by value.
At that point what is the use of pointers? |
2 main things:
1) They can point to an array
2) They can point to null (ie, they can be optional)
Passing by value
Passing by value creates a copy of the passed parameter. For basic types like int, this is cheap and fast, and therefore should be preferred for "input" parameters in functions.
The downside is that copying larger, more complex types like std::strings, or std::vectors, etc can be expensive. For example copying a vector involves allocating a new buffer to hold all the contents, then copying each individual element over to the new buffer.
If the vector has thousands of elements, you can see how this might get costly.
Passing by const reference
Passing by const reference (
void func( const std::vector<T>& v )
) does not create a copy, but lets you access the original object through a reference. However since the reference is const, it prevents you from modifying it... allowing the calling code to pass objects without fear that they'll be modified by the function.
This works well for large objects like vectors... but not necessarily for small types like int. Passing a reference is like passing a pointer a lot of the time... and passing a pointer means the function has to dereference it every time it access it... which is extra work. Whereas if it was passed by value, there would not need to be any dereference.
Passing by pointer
This can typically be used for 2 things. #1 is for passing variable size arrays:
1 2 3 4 5 6 7 8 9 10 11 12
|
void addOne(int* foo, int size)
{
for(int i = 0; i < size; ++i)
foo[i] += 1;
}
int main()
{
int array[5] = {1, 2, 3, 4, 5};
addOne( array, 5 );
}
|
And #2 is for "optional" output parameters. Since a pointer can be null... this gives you the option of passing "nothing" whereas with a reference you have to actually give it an object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
void doSomething( int* someoutput )
{
// ... do stuff here
if(someoutput)
*someoutput = foo;
}
int main()
{
int foo;
doSomething( &foo ); // here, I care about the output
doSomething( nullptr ); // here, I don't care
}
|