Easy pointer question

Started by
12 comments, last by Ashkan 16 years, 1 month ago
Sorry if this has been answered elsewhere but I couldn't seem to find anything and I'm a bit confused. Going through linked lists in my book and it has the following method:

template <class Entry>
void linkedlist<Entry>::copylist(listnode<Entry> *&newlist, listnode<Entry> *oldlist);



I'm a bit confused about the first parameter as I've never seen this before (the pointer to a reference). While I'm on the subject I've seen pointers that look like "double pointers" (e.g. **dblPntr) that I'm confused about as well. If someone could at least point me in the right direction on this I would appreciate it.
Advertisement
I'm note sure but could it be that for the listnode type the * or the & operator has been overloaded?

If not i would like to know the answer to your qestions also.
Unfortunately not, the listnode is a very simple class

[sourcelang="cpp"]template <class Entry>class listnode{	friend class linkedlist<Entry>;private: Entry *data;		 listnode *next;};
The type of the first parameter should be read as "reference to pointer to listnode<Entry>". It has the usual reference semantics, with modifications affecting the actual pointer passed as the argument.

To make it is hell. To fail is divine.

Zao:
I think I understand what you are saying. If I understand this correctly I can set this variable to NULL, and this would effect the "original" variable I passed to the function as well?
Exactly. A reference can be seen as an alternate name for the entity it references. Anything you do to it will happen to the original variable.

To make it is hell. To fail is divine.

Quote:Original post by gsGomer
Sorry if this has been answered elsewhere but I couldn't seem to find anything and I'm a bit confused. Going through linked lists in my book and it has the following method:

*** Source Snippet Removed ***

I'm a bit confused about the first parameter as I've never seen this before (the pointer to a reference).


Types are read backwards. (You wouldn't say "an int to a pointer", right?) So this is in fact a reference to a pointer-to-listnode<Entry>.

Quote:While I'm on the subject I've seen pointers that look like "double pointers" (e.g. **dblPntr) that I'm confused about as well. If someone could at least point me in the right direction on this I would appreciate it.


A pointer to pointer to T is simply a pointer to (pointer to T). Pointers are "things" in their own right, and as such, can be pointed at. And also referred to; hence the original question.
While **something is fine, I imagine that &&something is not. Am I correct?
Quote:Original post by Shakedown
While **something is fine, I imagine that &&something is not. Am I correct?


&&something is wrong (unless some strange operator overloading with unary '&' is taking place, but that is wrong on a whole different level).

What is fine is:
Something something;Something *onceRemoved = &something;Something **twiceRemoved = &onceRemoved; // almost like &&something
Put simply, you pass a function a pointer to T,

1) When you want to avoid the costs related with copying T back and forth, or

2) When you want to change T inside that function.

But accessing T via a pointer requires -> operator. Besides, every time you want to access the data that the pointer points to you have to dereference that which is a pain in the rear end and results in cluttered code, so you could have easily passed a reference in the first place and enjoy all the benefits of passing by reference (as opposed to passing by value) AND the freedom of changing T inside the function, but without all the hassles of dealing with pointer syntax. It has the same effect, you just let the compiler do all that pointer manipulation for you behind the scene.

You pass a pointer to pointer to T,

1) When you want to change the pointer that points to T, like when you want to let a function allocate some memory for you. The following code won't work.

void AllocateMemory( unsigned char* pBuffer ) {  pBuffer = new unsigned char[ 100 ];}int main() {  unsigned char* pBuffer;  AllocateMemory( pBuffer );}


Will the above code compile? Yes, but will that do what you're expecting from it? No. Why, you ask? I let you think on that and see if you can come up with a reason.

So, back to our discussion, it's obvious that you need one more level of indirection. All you need to do is to pass that function a pointer to a pointer to T, like this:

void AllocateMemory( unsigned char** ppBuffer ) {  *ppBuffer = new unsigned char[ 100 ];  // As a completely unrelated side note, what does the following code do?  // ppBuffer = new unsigned char *[ 100 ];}


But then again, you have to dereference that pointer to pointer to unsigned char to access the pointer to unsigned char, which is ugly at best. The solution? Pass a reference to a pointer to T, and again, let the compiler do all the nasty pointer manipulation for you behind the scene.

void AllocateMemory( unsigned char*& pBuffer ) {  pBuffer = new unsigned char[ 100 ];}

This topic is closed to new replies.

Advertisement