Thursday, February 7, 2008

C++ Pointers and References Basics

This will talk about how references and pointers relate to each other and highlight some of their differences.

Pointers and references are quite similar in what they do, as in they both utilise an already existant object/variable. However, they have a number of big differences. Pointers are more flexible, but can be a lot more dangerous, whereas references are somewhat more restrictive, but still very useful.

Ok, so here is an example of using both of them, starting with pointers. I will use the following class for illustration:
class SomeClass
{
public:
void setValue(int i){value = i;};
private:
int value;
}

So you can declare an object of this class, and then a pointer to the object like this:
SomeClass someObject;
someObject.setValue(55);

SomeClass *pToObj; //Not pointing to anything yet
pToObj = &someObject; //Pointer is initialised now
pToObj->setValue(11); //someObject.value is now changed

Pointers can be moved around and set any amount of times, so in the above example, you could set pToObj to point to another object, or something different entirely (which is why they can be so dangerous).

You are given a lot of freedom with pointers that can lead to problems, like the following where an unnitialized pointer is operated on:

SomeClass *pToObj2;
pToObj2->setValue(12); //BAD IDEA - CRASH!!


References on the other hand are much safer. They must be initialised, can only be initialised once (as a reference to some object/variable), and once they are initialised they cannot be changed.
So you can do something like this:
SomeClass someObject;
SomeClass &someRef = someObject;

But once this is done you cannot change someRef to reference another object of SomeClass (or anything else for that matter). Note that you have to initialise a reference. If you do not then the compiler will throw out an error.

There is a difference in notation when dealing with pointers and references. When accessing member variables / functions using a pointer it is done using the arrow notation. i.e.

pToObj->memberVariable;
pToObj->memberFn();

Whereas when using references, it is done using the same '.' notation as if you were using the object itself. i.e.

someRef.memberVariable;
someRef.memberFn();

References can be viewed as an alias for an object. It's like making an object of the LeadSinger class called paulHewson, having him make a band with some of his friends, and then make a reference to the paulHewson object called bono.

LeadSinger paulHewson;
paulHewson.makeBand();
LeadSinger &bono = paulHewson;
bono.sing(); //Both bono and paulHewson sing here as they are the same object!!

paulHewson and bono are just two different names for the same object. You cannot then go on and make bono into something else:

LeadSinger noelGallagher;
bono = noelGallagher;


You can, however, change pointers to point to other objects. So the following is possible:

Drummer johnPepys;
Drummer ericChilds;
Drummer peterBond;
Drummer *pSpinalTapDrummer = &johnPepys;

johnPepys.DieInGardeningAccident();
pSpinalTapDrummer = &ericChilds; //Same pointer, different object
ericChilds.ChokeOnVomit();
pSpinalTapDrummer = &peterBond;
...
and so on
...



I think that covers the basics, I've got a fair bit more to write about pointers and references in posts to come, but that's enough for now!

--
Lurning Man
--

No comments: