tags:

views:

187

answers:

4

If a HANDLE is an output parameter, is it necessary to use a reference to the HANDLE or use HANDLE directly?

bool fn(HANDLE h_result);

or

bool fn(HANDLE& h_result);
+11  A: 

To return values you can:

  1. Use a reference as a parameter
  2. Use a pointer as a parameter
  3. Actually return the value via return

When you specify the following:

bool fn(HANDLE h_result);

You are making a copy of h_result. So if you change it in your function, you are changing the copy, not the original.

When dealing with pointers, the concept is exactly the same. Just remember that a pointer is simply a variable that holds a memory address. It doesn't matter what's in that memory address. If you want to return a memory address via a parameter, then you need to use a pointer to a pointer or a pointer reference.

Brian R. Bondy
A: 

If you use "HANDLE" directly, none of the changes you make inside the function call will be conveyed to the object at the caller.

e.g. For "bool fn(HANDLE h_result);"

HANDLE oH = CreateHandle(); // Some function
oH.SetName("Sam");
bool bRet = fn(oH);   // Assume we call oH.SetName("Max");
cout << oH.GetName() << endl;  //will print "Sam"

But if you use "bool fn(HANDLE& h_result);" the output would be "Max"

So the choice would depend on the application. If you need to maintain state changes made in "fn", pass the parameter as a reference. If not, pass a copy by using "bool fn(HANDLE h_result);"

P.S. The "bool fn(HANDLE h_result)" would be quite heavy on processing since there are a lot of calls to the copy constructor

Gayan
+1  A: 

In your case, I would rather do something like:

HANDLE fn()

and return an invalid (or NULL) handle in case of failure and a valid handle otherwise. Of course, I am assuming that the HANDLE type is someway similar to what Win32 API uses as handle.

As for your question, pass output parameters by reference or by pointer, so either:

bool fn( HANDLE& out)

or

bool fn( HANDLE* out)

In the second example, you should make sure that the passed pointer is not NULL, usually with an assert:

bool fn( HANDLE* out)
{
   assert( NULL != out);
   // ... rest of the code
}

Another disadvantage of passing the output parameters as pointers is that you can't know for sure if the passed pointer is valid or not (was initialized or not).

Passing by reference is sometimes less readable when it comes to output parameters. Calling

bool result = fn( myHandle);

doesn't give a hint to the developer that myHandle is an output parameter, and some subtle problems may occur due to code readability.

In conclusion, I recomend to avoid as much as possible output parameters, because of the code readability, but, if you really have no choice, use references instead pointers, if the output parameter is mandatory.

Cătălin Pitiș
+1  A: 

A HANDLE is basically a void*, that's all. Change the code in question to

bool fn(void* pResult);

and the answer will be clearer. If you want the value assigned to pResult to be available to whoever called fn, you'll have to change the function to

bool fn(void*& pResult);

which is equivalent to

bool fn(HANDLE& h_result);
eran
Andrey