Pointers vs References
| BlahBlah (7) | |||
| Would it be better to use pointers or references to pass varibles in and out of a function? Thanks! | |||
| QWERTYman (252) | |||
| As far as simplicity, references would be better than pointers. No using stuff like having to assign pointers to addresses. However, I guess that a reference is rather like a constant pointer, meaning that
int & x = bob;is basically
const int * x = &bob;so it doesn't really matter, as far as I know. | |||
| helios (829) | |||
| I have always preferred pointers due to their explicitness. If you look at a pointer you can know it's one because it uses a different syntax than variables and objects. References, however, don't. What the hell? This is valid:
| |||
| Zhuge (102) | |||
If I remember the syntax for const pointers properly, I think it is valid because
b is a pointer to a
const int;
b itself is not a constant pointer. Therefore, I see no reason why you could not increment the pointer's value. | |||
| Umz (133) | |||
| I normally use references to pass variables with functions but I'd say it depended on the rest of your code and what you were doing. Might as well learn to do both since they have there uses. Example:
| |||
| jsmith (711) | |||||
| No no no no no. ALWAYS use references when possible. NEVER use pointers unless absolutely forced. Simple. For three reasons: 1) QWERTYman is partially correct. References are pointers, but non-const references are non-const pointers and const references are const pointers. It is REALLY HARD to make a NULL reference but VERY EASY to make a NULL pointer. By declaring parameters to functions as pointers, you FORCE yourself to write defensive code inside the function to check the pointer for NULL before accessing. And then you FORCE yourself to figure out how to handle the error case. 2) When doing generic programming it is easy to write a template function that works on variables passed by value or by reference since the syntax for accessing either is the same.
3) Pointers and operators don't mix well. For example, given a pointer to a std::map< int, int >, how to you call operator[]?
| |||||
| helios (829) | |||
| It may be ugly, but it's explicit. You can tell by simply looking at it that aMap is a pointer. While it is true that null pointers may be passed as function parameters, this has positive aspects. For example, suppose you have an openFile() function, and you want that when a file name is not passed to it, to open a certain file by default. Since you can't pass a null reference, you are FORCED to pass it an empty string of some kind, which is of course slower, particularly if using std::strings. And of course, you can also return null pointers, making it easy to distinguish special situations (see strpbrk() for an example) In the above code, this also worked: int const *b=a; EDIT: Hmm... The compiler complains "increment of read-only location" if I use (*b)++ is b is both 'const int *' and 'int const *'. This is why I never use consts. | |||
| jsmith (711) | |||
| I agree that there are times when pointers are preferred, and the two cases you mentioned are perfect examples. The problem I find with a lot of production code that uses pointers is that while the NULL pointer error conditions might be handled by checking for NULL, they are almost never handled correctly in a large complex system. It's also said that 75% of all code written is handling error cases, so I try to minimize the number of possible errors. While it is possible to write a function that returns an error code in the event of an erroneous NULL pointer, I find that a lot of programmers either ignore the return code altogether or they don't give enough thought to how to recover from the error condition with the justification that it "should never happen". | |||
| satm2008 (143) | |||
| @QWERTYMan & jsmith First, references are NOT pointers. A reference is just "like" a const pointer meaning once a reference is initialized it can not be reseated. A reference is an alias for the referrant object, meaning, underneath it represents the address of referred object, but has no "separate" identify nor is a "sepearate entity". If you check the address of reference and referrant object, both return same, unlike a pointer. A pointer is a separate entity which has its own address and stores/represents another memory address. And, I suppose you mean, int & x = bob; is basically int * const x = &bob; // not same as, const int * x = &bob; (Read from right-to-left) int * const x; // here x is a constant pointer pointing to an integer object, meaning the pointer can not change its address once set int const * x; // here x is a pointer pointing to a constant integer, meaning the pointed-to object can not change it's value once set And, coming to the difference, int a = 10; // assume it is stored address 0x123 int &b = a; // b is just an alias for a, and not a separate entity, meaning, it represents same 0x123 int *p; // p is a poiter and has its own identity and is a seperate entity at 0x126 p = &a; // points-to another memory location, which is of a cout << "&a " << &a << endl; // prints 0x123 cout << "&b " << &b << endl; // prints same 0x123 cout << "&p " << &p << endl; // prints 0x126, definitely not 0x123 Check the given above example and you find the difference yourself. Good luck :) | |||
| satm2008 (143) | |||
When you write a library function and would not provide the library (with the .h code) to the client or other team, the function call in the caller program would not show that the function is called "by reference" hiding the fact that the referrant arguments passed-in could be "modified". But if it is a pointer, it clearly shows/requires to pass-in an address for each pointed-to arguments/parament so that the caller function tells you that it is called by reference and could be modified within the called function. In the first reference case, it would not be a user or developer friendly as it causes confusion in code development/debugging process. Check it out. Good luck :) EDIT: Yes, I forgot that we provide .h file with prototypes etc so they show which one is what, by reference, constant, or value. So this is out of context :) | |||
| helios (829) | |||
| Dear sir: I reject your argument about the nature of references as compared to pointers on the grounds that you are a noob. -Helios | |||
| satm2008 (143) | |||
| @helios Are you pointing at my post? If so please check the given example and let me know where if I am missing. You would know what I am talking about if you are an experienced C++ dev, then you would know who is noob :) Good luck :) | |||
| jsmith (711) | |||
| Uh, I agree with helios. satm2008, you are a noob. Or else all those years programming in C++ were wasted because you obviously haven't learned much. When you provide a library to someone you give them the header files. The header files contain the declarations of the functions. The declarations of the functions show the type of each parameter. Either the parameter is a reference or it isn't. When you accept a parameter by non-const reference you are telling the caller that they should not rely on the value of the actual parameter being the same post-call. When you accept a parameter by const reference you are telling the caller that they can rely on the value of the actual parameter being preserved across calls. Same goes for pointer and pointer-to-const. | |||
| satm2008 (143) | |||
| Which one are you pointing to, the diff between pointer and reference or other my second note, reference in functions. On the second note, yes, I agree with you as the prototypes show what is what. I missed that. Just out of curiousity, when would you say some one noob??? | |||
| helios (829) | |||
| I was referring to the first post. References are pointers, it's just that, once they are initialized, the language hides that fact from you by immediately returning the value they point to (without copy, of course) without any extra syntax. References are just pointers minus an asterisk, and if this wasn't the case it would be impossible to pass parameters by reference using references. | |||
| satm2008 (143) | |||
| @helios, Nope, I dont agree with you that they are same. They act as same, with a difference in reference and dereference, they are not same. As given in the example, a pointer is a separate variable holding an address of other while allowing to be changed, where as, a reference is not a separate entity (ie. just like an alias) and can not be reseated. A reference acts like a constant pointer, but it is not a pointer. A variable/identifier is a name for a memory location cotaining a regular value, the same is, reference. A pointer is a variable, holds the address of a memory location and allows to be manipulated (including pointer arithmatics). For your confirmation, check the assembly or compiler-generated code for a reference given in a program. Agree or not, that is the fact. Good luck :) | |||
| helios (829) | |||||
Okay, I just did. Here's my C++ code:
And here's the disassembly (a quick summary at the bottom):
Now, if you take a close look at lines 12-17 and 39-44 in the disassembly, where the dereference is performed, you'll notice that those blocks are identical. You can also see in lines 68-70 and 71-73 that the initializations of b and c are identical, as well. Now, then. Are references aliases, or obscured pointers? | |||||
| satm2008 (143) | |||
| I m not familiar with an assembly language, so, I can not justify it by seeing the attached code. What compiler are you using? Did you check the example I gave? | |||
| helios (829) | |||
VC++
This discussion is over, then. | |||
| jsmith (711) | |||||||||||
Ok, satm2008...
Wrong for two reasons, at least as I interpret your statement. The following works just fine: int x; int y; int& ref = x; ref = y; // "Reseating" a reference. I do not believe that the C++ standard mandates how compilers must handle or implement references, however as helios says and I can also confirm, gcc implements references by using pointers. That is, internally:
If you were to dump the contents of the memory locations occupied by ref and ptr you would find they are identical. A non-const reference works the same as a pointer-to-non-const. A const reference works the same as a pointer-to-const.
Ok, I partially agree with this. Given
Outputs the same value. This is because the syntax of accessing variables via references is the same as accessing variables directly. That mans that in the above code &ref is actually the same as &x. That is, it is not possible to take the address of a reference variable. However, that does not mean that references are free. They essentially consume the same amount of memory as a pointer.
Hence I don't agree with your statement that pointers are separate entities and references are not. Internally they are clearly both separate entities.
Yes, you are seeing this because the language does not allow you to take the address of a reference variable. &b is NOT the address of b. b indeed does have an address.
| |||||||||||
Pages: 1 2
This topic is archived - New replies not allowed.
