First, this "speed" notion depends entirely on what we are comparing.
An integer, for example, is usually about the same size as a pointer, depending on how the integer is declared.
There is no difference in speed when pushing a copy of an integer when compared to pushing a pointer to an integer, or a reference to an integer.
The speed difference comes into play when passing larger structures (classes, structs) by value, as compared to pointer or reference.
If you're passing structures to a function, you probably want the speed benefit, so unless there is a reason to want a copy (a duplicate/constructor/destructor implied), you don't want to pass those by value.
If you're passing anything, int, float, structure....
and you want the calling code to receive the changes made to those values inside the function, you can't pass those by value.
To be clear:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
void f1( int a ) { a *= 2; }
void f2( int & a ) { a *= 4; }
void f3( int * a ) { (*a) *= 8; }
int main()
{
int x = 5;
f1( x ); // x is still 5, f1 used a copy
f2( x ); // x is now 20, it did not use a copy
f3( x ); // x is now 160, it did not use a copy
return 0;
}
|
If you don't need or care that the caller will not see the changes made inside the function, you can pass by value (the function uses a copy).
If you need the calling code to be aware of the changes made to the value inside the function, as in f2 or f3 above, you can't pass by value (you could use a return from the function, but that's another subject).
Now....about pointer vs reference.
The pointer is from C. It is from the origin of the language back in the 70's. It is an older concept.
In Modern C++ we avoid pointers wherever possible. This implies you should prefer references unless you have no choice be to "devolve" toward a pointer.
Raw pointers come at us from the operating system, as most operating systems are written in C.
Sometimes you're working at a raw level for the sake of extreme performance, and you may create some custom memory management system, or you're processing video data, audio data, image information...the point here is that by the time you're doing that stuff, you know you need pointers and don't need to even ask anymore.
Until you're going that, you're best to avoid pointers entirely until you're ready to really study them (and their usage).
In the 90's, we might:
A * p = new A();
We'd do this for dynamic allocation of A. Maybe A is polymorphic (has a virtual base class). For whatever reason I could not just use an "A" on the stack, if I just had to make one from the heap (that could survive beyond the local function, for example), then I must create it with new.
Until modern C++.
Now, one should far prefer:
std::unique_ptr< A > p = std::make_unique<A>();
Or the related "make_shared" if using shared_ptr.
Here, there are no naked pointers. "p" will still work like a pointer, fast as a pointer, and "A" is dynamically created. However, I will not have to remember to delete it. That will work automatically.
I also can't accidentally delete it twice because I screw up the management of a raw pointer that owns it.
...and a bunch of bugs associated with raw pointers.
Now, one of the things you didn't ask about is implied with:
void f( std::unique_ptr<A> & p );
That might not strike you, so look at the rawer version of it
void f( A *& p );
That's a reference to a pointer.
Do not blow a fuse contemplating it. It's rather simple, and has a purpose, just something more to contemplate (and there's more, but I'll pause here).