I'd much prefer to use references everywhere but the moment you use an STL container you have to use pointers unless you really want to pass complex types by value. And I feel dirty converting back to a reference, it just seems wrong.
Is it?
To clarify...
MyType *pObj = ... MyType &obj = *pObj;
Isn't this 'dirty', since you can (even if only in theory since you'd check it first) dereference a NULL pointer?
EDIT: Oh, and you don't know if the objects were dynamically created or not.
Dereferencing a pointer means getting the value that is stored in the memory location pointed by the pointer. The operator * is used to do this, and is called the dereferencing operator.
A pointer to reference is illegal in C++, because -unlike a pointer- a reference is just a concept that allows the programmer to make aliases of something else. A pointer is a place in memory that has the address of something else, but a reference is NOT.
You would want to pass a pointer by reference if you have a need to modify the pointer rather than the object that the pointer is pointing to. This is similar to why double pointers are used; using a reference to a pointer is slightly safer than using pointers.
Once a reference is established to a variable, you cannot change the reference to reference another variable. To get the value pointed to by a pointer, you need to use the dereferencing operator * (e.g., if pNumber is a int pointer, *pNumber returns the value pointed to by pNumber .
Ensure that the pointer is not NULL before you try to convert the pointer to a reference, and that the object will remain in scope as long as your reference does (or remain allocated, in reference to the heap), and you'll be okay, and morally clean :)
Initialising a reference with a dereferenced pointer is absolutely fine, nothing wrong with it whatsoever. If p
is a pointer, and if dereferencing it is valid (so it's not null, for instance), then *p
is the object it points to. You can bind a reference to that object just like you bind a reference to any object. Obviously, you must make sure the reference doesn't outlive the object (like any reference).
So for example, suppose that I am passed a pointer to an array of objects. It could just as well be an iterator pair, or a vector of objects, or a map
of objects, but I'll use an array for simplicity. Each object has a function, order
, returning an integer. I am to call the bar
function once on each object, in order of increasing order
value:
void bar(Foo &f) { // does something } bool by_order(Foo *lhs, Foo *rhs) { return lhs->order() < rhs->order(); } void call_bar_in_order(Foo *array, int count) { std::vector<Foo*> vec(count); // vector of pointers for (int i = 0; i < count; ++i) vec[i] = &(array[i]); std::sort(vec.begin(), vec.end(), by_order); for (int i = 0; i < count; ++i) bar(*vec[i]); }
The reference that my example has initialized is a function parameter rather than a variable directly, but I could just have validly done:
for (int i = 0; i < count; ++i) { Foo &f = *vec[i]; bar(f); }
Obviously a vector<Foo>
would be incorrect, since then I would be calling bar
on a copy of each object in order, not on each object in order. bar
takes a non-const reference, so quite aside from performance or anything else, that clearly would be wrong if bar
modifies the input.
A vector of smart pointers, or a boost pointer vector, would also be wrong, since I don't own the objects in the array and certainly must not free them. Sorting the original array might also be disallowed, or for that matter impossible if it's a map
rather than an array.
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