Best Way to Pass by Refence in C++

Started by
17 comments, last by snk_kid 18 years, 10 months ago
For functions in classes, what is the best way to pass by reference? I assume it is good to keep consistency in applications, so I was wondering should I use void Test(Tile &InTile) { } or void Test(Tile *pInTile) { } I know I am probably being a bit fussy, but I would like to get this right from the start.
Advertisement
void Test(Tile &InTile){}// in C++ this is the best wayorvoid Test(Tile *pInTile){}// in C this is the best and only way

Beginner in Game Development?  Read here. And read here.

 

I prefer to pass by reference(as opposed to pointer) because a reference cannot have a null value like a pointer can. Besides being safer, the syntax is nicer since to don't need to take an object's address when passing it in. I hope this helps.

-Scott
For input parameters (those that are not modified), you should use:
void func(const MyType& param);

For output/inout parameters, you should use:
void func(MyType* param);



Using a reference for output parameters my lead to programming errors. Consider a function declaration like this:
void func(MyType& param);

The you would call it like this:
MyType myValue;
func(myValue);

It's not obvious from the call itself, that you call by reference instead calling by value (*). But if you used a pointer, you had to write this:
MyType myValue;
func(&myValue);

Here you can clearly see (when calling the function), that the function is able to modify the parameter. This avoids much confusion when reading your source code, especially if you can't remember the signatures of 1000 functions at once.


(*)
Pass by value:
void func(MyType myValue);
I would use references as much as you possibly can - if you're worried about altering values then use consts.

References look so much cleaner - no unneccasary dereferencing etc, and no worrying about NULL or uninitialised pointers.

There are situations however when pointers the only alternative - but I would try and keep these to a minimum to save debugging time.
-Scoot
Quote:Original post by nmi
Using a reference for output parameters my lead to programming errors. Consider a function declaration like this:
void func(MyType& param);

The you would call it like this:
MyType myValue;
func(myValue);

It's not obvious from the call itself, that you call by reference instead calling by value (*). But if you used a pointer, you had to write this:
MyType myValue;
func(&myValue);

Here you can clearly see (when calling the function), that the function is able to modify the parameter. This avoids much confusion when reading your source code, especially if you can't remember the signatures of 1000 functions at once.

Which parameters will and will not be modified should be clear from the function name. Using pointers adds the possibility of being passed invalid memory, which is considerably worse than forgettining which arguments might be modified. References don't suffer from this problem.

CM
Use references as much as you can but don't forget that sometimes pointers are the best or easiest way to go, for example its easier to make an array of pointers than it is to make an array of references and its sometimes nice to be able to pass NULL (although I prefer to use 0 rather than NULL)

'highly' portable code might use pointers because C doesn't have references (pointers are the ONLY alternative to pass-by-value)

But don't pass everything by reference eg passing an integer by value is better than by reference, only pass complex types by reference (unless you plan to modify it within the function and DON'T want it to affect the object outside the function)
Great advice, thanks guys. It seems the concensus is to use pass by reference then. It that case, my final question is... using hungarian notation, which is the right format?

void Test(Tile &InTile)
{
}

or

void Test(Tile &pInTile)
{
}

Should it still be declared within the function as a pointer?

Thanks again all!
Quote:Original post by Raeldor
Great advice, thanks guys. It seems the concensus is to use pass by reference then. It that case, my final question is... using hungarian notation, which is the right format?

void Test(Tile &InTile)
{
}

or

void Test(Tile &pInTile)
{
}

Should it still be declared within the function as a pointer?

Thanks again all!

The right format is probably not to use hungarian notation at all. Either way, there's no need to add the p. That's intended to remind you to dereference it and what not, none of which is necessary with references. For all practical purposes, they're just like any other variable.

CM
I consider hungarian notation the tool of the devil who will laugh at you if you ever try to change the type of a variable...

That said, definately not p, since it's not a pointer.
Maybe r or ref, or prehaps none extra (e.g. Tile & ____ would be the same as Tile ____, since they act exactly the same).

This topic is closed to new replies.

Advertisement