Until I started to work, there wasn't much chance for me to look at how real world code really works. In other words, I programmed in my own fashion and I only had to use my own codes. However, I had to write MFC applications as I started to work. I realized that many of the methods for MFC were written and used very differently from how I used to write methods.

When passing by parameter to a function in an in/out fashion, I usually use the following function signature.

// Foo case: parameter is passed by reference
void Foo(int& a);

But, the functions or methods written for MFC usually use the following signature for in/out parameters.

// Bar case: parameter is a pointer type
void Bar(int* a);

So, what's the difference?
Here is my explanation according to my opinion. The function signature that I usually use for in/out parameters explicitly shows that it is passed by reference like the Foo case. I say "explicit" because you can know the parameter is passed by reference just by looking at the function signature. However, in the Bar case, the parameter is passed by reference implicitly by passing a pointer type. Even though they both have the same affect on the parameter, the Bar case does not necessarily mean that the parameter is passed by reference. They both have the same affect on the parameter, but keep in mind that all parameters are passed by value in C++. Therefore, passing a parameter by reference only works by passing an address of a variable (or an object). For that reason, I am saying that passing a pointer to a function does not necessarily mean that you want the parameter to work in an in/out manner.

Sometimes you simply want to pass a pointer. In that case you should limit the side affect on the parameter by using the const keyword. So, if that is the case function Bar should be written

void Bar(const int* const a)

but let's don't discuss that here.


On the other hand, the situation looks slightly different in the client code like the following.

int b;
Foo(b);     // calling Foo(int& a)
Bar(&b);   // calling Bar(int* a)

By looking at the code, you won't be able to tell whether b is passed by value or reference for Foo. Since the parameter passing scheme of Foo is indeterminable in the client code, I personally think that using a pointer type for in/out parameter is better to use than passing a parameter to a function by reference explicitly in the function signature (in other words Bar is better than Foo). Using the '&' to declare the parameter to be passed by reference in the function signature makes the intention clear in the function signature itself only. But by using a pointer type parameter, you can at least guess that the parameter is in/out by looking at the function signature and maybe it becomes clearer when you look at how it is used the client code. Besides, as I mentioned in the colored quoted section above, if you want to pass a pointer to the function and avoid side affects, you should use the const keyword.

So, my conclusion...
For code readability issues, I personally think that functions that require in/out parameters should be written in the Bar way rather than the Foo way.




Posted by Dansoonie