views:

229

answers:

3
char *str = "Hello";

char *ptr = str;
char *&rptr = str;

What is the difference between ptr and rptr? I understand rptr is a reference to a pointer(in theory) but how does it differ in terms of implementation with ptr?

Are references in C++ implemented using pointers?

+5  A: 

What is the difference between ptr and rptr?

If you do char *world = "World"; rptr = world; and then print str, it will print "World". If you do ptr = world; and then print str, it will print "Hello".

sepp2k
i.e., rptr is an alias to string, ptr is a mere copy. If you point str somewhere else, it will affect rptr, but not ptr. In other words, you could say that str and rptr are 2 different variables (2 different names), but the same pointer.
apollodude217
While indeed the gist of your answer is correct, notice that you cannot do `rptr = "World"` because `"World"` is not a `char*` pointer. The implicit conversion of the char array to a char pointer won't be done here, because it's a non-const reference.
Johannes Schaub - litb
@sepp2k it's still wrong. Let me fix the code to show you what is wrong. Now you have got same situation: You have an array but you try to bind a non-const reference to a `char*` to it - it won't work. It's just like `float a = 0; int ` fails. It's easy to overlook, but just as easy to understand once you see what's up here.
Johannes Schaub - litb
@JohannesSchaub-litb: My edited code compiles in g++ with -Wall -pedantic -ansi without warning. Note that I'm not doing `char*`, I'm doing `char* something = anArray;`.
sepp2k
@sepp2k ohh i see now. I'm sorry for being that stupid. I even tried with codepad.org before to double-check, but i totally missed that this is really just an assignment. Lemme get another cup of coffee now. Cheers!
Johannes Schaub - litb
@sepp2k: What is the significance of this statement char* something = anArray; Are you doing this because you cannot directly point a string literal (ie "Hello") using char* directly as per the standard.
Sam
+3  A: 

Try this:

#include <iostream>
int main () {
    char *str1 = "Hello ";
    char *str2 = "World!";
    char *ptr = str1;
    char *&rptr = str1;
    rptr = str2;
    std::cout << ptr << str1 << std::endl;
}

It prints "Hello world!" because ptr is a char pointer pointing to the string literal "Hello ". rptr is a reference to a char pointer, so when you change it (the pointer, not the thing it points at.) you change str1. And thus ptr points to "Hello ". str1 points to "World!".

Kleist
+1  A: 

str stores the address (and therefore points) to a literal string, "Hello", which is stored somewhere in a read-only segment of memory.

ptr points to the same address as 'str'.

rptr basically points to 'str' (not to the same pointee as str, but to str itself). It might be unusual to use 'points to' for references but they're really very much like pointers themselves (in this case a pointer to a pointer) except with slight syntactical differences and the restriction that they cannot point to any other address during their lifetime.

It would be analogous to:

char** const rptr = &str;

Like a reference, rptr above cannot be assigned a new address (it cannot change what it's pointing to), but it can be free to change its pointee (which happens to be a pointer in this case to 'str').

*rptr = 0; // after this, str == 0

References are pretty much the same as a read-only pointer (not a mutable pointer to read-only pointee) only they don't require a dereferencing operator to get at the pointee (the referenced data):

char *str = "Hello";
char *&rptr = str;
rptr = 0; // after this, str == 0

The only difference from the above example with a read-only pointer to pointer is that we didn't have to use the operator*.

const references also have the unique property of being able to extend the lifetime of temporaries, but that's probably beyond the scope of the discussion.