Reputation: 21
I'm wondering which one is better of these two implementations of passing addresses to pointers. Is there a data exchange in the 1st one that doesn't happen in the 2nd one? Is the second one a more efficient way? More readable? both the same?
Version 1
void ptrFunction(int& arg)
{
int* ptr = &arg;
std::cout<<"The pointer's value:" << *ptr << "\n";
}
int main()
{
int x=5;
ptrFunction(x);
return 0;
}
Version 2
void CallViaPointers(int *arg)
{
int *ptr = *arg;
std::cout << "The pointer's value: " << *ptr;
}
int main()
{
int x = 100;
CallViaPointers(&x);
return 0;
}
Upvotes: 2
Views: 129
Reputation: 14212
int *ptr = *arg;
Should be:
int *ptr = arg;
I find the reference parameter more readable than the pointer parameter when it is not clear the parameter will be used as a pointer somewhere else. This is usually the case, and use of parameters is often encapsulated so callers don't care about implementation details. However, you may have to conform to an existing interface, and that may be using pointers as iterators – then you're "passing an iterator by value" (the usual way to pass an iterator) rather than "passing a pointer to an object", even if that iterator is actually a raw pointer type. (Other types of existing interfaces are possible.)
Beyond the above, personal preference, and one allowing null pointers (you cannot have a null reference), they are identical in every way.
Upvotes: 1
Reputation: 4514
They are equivalent, and this can be verified by compiling and checking the disassembly - it's identical other than symbol names.
As for style, it's mostly a personal preference, but there is a common pattern of using a pointer for out-parameters. This is because when you take a reference, it's not clear if the function you're calling is going to modify it. "Effective C++" uses const references for in-parameters and non-const pointers for out-parameters. I find this a good way to make it clear what the contract is.
Upvotes: 1
Reputation: 503873
I'd say it depends on what the function does. Right now your function name doesn't match what it does. If it did, it'd be named (I read the question incorrectly. But yes, it still depends on what your function does.)print_pointer
and it'd be clear it should just take a pointer directly.
Let's say you have a function that prints a pointer, like:
void print_pointer(void* ptr)
{
std::cout << ptr << std::endl;
}
It doesn't make sense for this function to be written to take a reference, then get the address of it, because you don't want an object, you want a pointer to an object, and null is valid in this context.
If, however, you need an object, like your code does, you should take a reference, because pointing to that object is an implementation detail; the interface, with a reference, clearly documents you need an object to refer to.
As it stands, version two is broken, because passing null crashes the program, yet null is a valid pointer value. Don't advertise you want a pointer value when it isn't the case. To fix it, check for null and do something clearly documented, like nothing or throw an exception. But best it to change the parameter to a reference, because you leave those issues to the caller, and your function works regardless.
(If someone has a pointer to an object, they can be responsible for dereferencing it safely to pass a valid object to your function. In other words, using a reference is self-documenting: "null isn't valid here".)
Performance is irrelevant.
Upvotes: 1
Reputation:
Performance wise, it depends entirely on the implementation, of course. Generally, they will compile to the same machine code. And this is definitely one of those cases where you should not think about optimizations at all unless you have to. Readability is much more important in most code.
As for readability, I tend to prefer version 2, because I want the user of my function to know that I'm going to (or able to) modify whatever he puts in there, but there are exceptions to this rule (such as when catching exceptions, or for operator overloading).
Upvotes: 1
Reputation: 372814
In terms of efficiency, the two will almost certainly compile down to the same code behind-the-scenes, as references are often implemented as automatically-dereferenced pointers. From that perspective, the two solutions are equivalent.
As for whether to pass by pointer or by reference, that's really a judgment call that depends on the situation. If what you're trying to do is just print out a pointer to the integer (as you're doing here), then pass-by-pointer makes a bit more sense because it's more explicitly aligned with what you're trying to do. In general, write the function so that the parameter is of the type you want internally. If you need a pointer - either because you're building a linked structure or because you're doing some sort of memory allocation - then take in a pointer. If you're dealing with polymorphic classes, then traditionally you would accept your argument by pointer rather than by reference, though both work. If you're taking in a stack-allocated object to try to modify it, then the reference can be a bit clearer. And, if you're in one of those situations where you must use a reference - for example, as a parameter to an overloaded operator, copy constructor, or assignment operator - then of course go with the reference. Readability is really undervalued these days, but making the effort to have clean, readable, intuitive code is definitely worth the effort.
Upvotes: 4