I have read a number of stackoverflow answers about this and I am not quite satisfied from the responses so I wanted to gather them here.
When calling a function using non-primitive and complex objects for parameters it is generally advised to pass them by reference UNLESS there is a possibility of the parameter being NULL. This is mostly due to the fact that references are guaranteed to have a value so you don't have to check if a parameter reference is NULL.
When the return value of a function is a non-primitive and complex object you should generally return a pointer because it is easy to confuse a function that returns a reference with one that returns a value as they appear identical when called.
As an example take this class
struct Rectangle
{
int x, y;
int width, height;
Rectangle(int x_, int y_, int width_, int height_)
: x(x_)
, y(y_)
, width(width_)
, height(height_)
{
}
};
class Image
{
public:
Image()
: dimensions(0, 0, 0, 0)
{}
~Image();
void SetDimensions (const Rectangle& newDimensions) // Pass by reference is recommended practice
{
dimensions = newDimensions;
}
Rectangle GetDimensions() // Returning by value is usually the best practice in this case
{
return dimensions;
}
private:
Rectangle dimensions;
};
Are these the best practices for references vs pointers in function parameters and return types? If not, please explain why not.
EDIT 1: Changed GetDimensions() to return value because it is believed efficient
References are usually preferred over pointers whenever you don't need “reseating”. This usually means that references are most useful in a class's public interface. References typically appear on the skin of an object, and pointers on the inside.
It's much faster and memory-efficient to copy a pointer than to copy many of the things a pointer is likely to point to. A reference is stored in as many bytes as required to hold an address on the computer.
Difference Between Reference Variable and Pointer Variable: A reference is the same object, just with a different name and a reference must refer to an object. Since references can't be NULL, they are safer to use.
As a rule of thumb, passing by reference or pointer is typically faster than passing by value, if the amount of data passed by value is larger than the size of a pointer.
A reference is a reference and a value is a value. They've different semantics and only thinking to the performance of saving a copy operation can become a serious problem.
More specifically in theory references should be used only when the receiver cares about the identity (and not just about the value) of the object. Values should be used instead if the identity is not important and the called function/method cares only about the value.
If you're absolutely sure that you're not going to run into aliasing or lifetime issues then you may decide to pass a const reference instead of a value to save the copy operation.
In this answer there's a detailed example (that, incidentally, is also talking about rectangles) of the kind of very subtle bugs that you may run into by passing references when values should have been used instead. And note also that const-correctness is not going to be of any help when dealing with aliasing and lifetime issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With