Should I use pointers all the time in C++?


Contrary to most answers here, I have no particular aversion to pointer implementations in C++.

To me, a pointer is just a variable. So saying ‘pointers are bad’ is saying variables are bad. After all it is really just an unsigned integer that contains an address and has a type associated with it.

An indirect reference serves a purpose. It allows access without copying and replacing values and allows objects to cross context boundaries. Of course the possibility of abuse and error is present in such situations, but it always is anyway really. Any variable can contain a bad value, be it a pointer or a direct variable.

C++ has some tricks up its sleeve with references, lvalue references, smart casting, etc, that do indeed make for safer code constructs when indirection and pass-by-reference is used — which is all the time. Of course it is encouraged to use these tools to write more robust and reusable code.

But it is not altogether possible to avoid pointer implementations in a lot of situations, so to be ‘afraid’ or revulsed by them is to throw away some essential programming tools.

Look into the STL and you will find a lot of pointer stuff in there.

Almost any time you need to interface with C code you are going to be passing pointers around. You have to; that’s how C operates on anything more complicated than a primitive value.

Most of the STL library utilities and object have pointer-return and pointer-parameter functions for this purpose.

“Never Use Pointers” is like saying “Never Peel Oranges and Never separate orange into slices — the only way is to chomp down, peel and all. After all , raw orange internals are delicate and you could break them and leak juice all over!”

You learn how to safely use pointers and when there are better ways to get a job done (and when there aren’t). If you are not comfortable with pointers and how to use them, then that is a hole in your education, not a good thing. If you must abstract your programs up and away from memory locations and allocation and referencing, well then perhaps a hardware-facing, compiled systems language that is a super-set of the C language is not the language you should be learning.

That is not to say refactoring out raw pointers is not necessary or preferable in a lot of cases. The additional mechanisms for indirection and referencing in C++ over C are there to help facilitate safer code and they should be used, preferred, and leveraged to the hilt.

Pointers make sense at times. Most of the time in a pure C++ environment they can be avoided, as references and default pass-by-reference semantics take over most of cases, (but not all cases, that is my whole point). Internally to the STL and the language itself, pointers are everywhere anyway. It is how computers work, by loading up values from addresses and jumping around memory locations poking and peeking bytes. So eventually you are going to have to directly do some of that in your code, because you are accessing hardware.

Pointers get a bad rap because they are stupid containers compared to C++ references or Class variables. They give no information to the compiler or to the code writer if they contain garbage, a valid reference, or nothing. Or if they point to the correct object at the moment. Pointers force a hyper vigilance on the writer to get it right and anticipate that errors will occur unless you write code to ensure correctness and handle problems. Pointers are from C, and they bring with them all the power of C, and all the problems of C as well. But they are so versatile and easy to use that mistakes that can cause catastrophic failure are super easy to make and often hard to detect at compile time. That is why C++ created references to specifically disallow and try to correct some of the biggest shortcomings and risky aspects of pointers, not because pointers are unnecessary.

C++ references force a compiler to do a code-review checklist of the most common and egregious pointer-implementation errors and pass/fail on the code as written.

Almost all the things you can’t do with a reference are rules of what you shouldn’t do with pointers.

This leads to an adhoc rule-of-thumb: If you have to do an operation that a reference will not do, then maybe you can use a pointer and do it that way. But probably you need to rethink the operation and do it slightly differently.

BTW lets talk about iteratorsIterators are not technically pointers. They are defined as their own special type , but look into them and you will see they bear a great resemblance to pointers in both aspect and use. C++ STL container iterators are a wonder, but they mostly model C pointer iterator idioms.

STL iterators are safe to use because of extensive safety checks by smart boys and girls internally, and yes most are actual pointers in the STL source code. But there is not a scared mob of foaming-at-the-mouth code bullies screaming about them like there is about C style pointer implementations.

DON’T DO THIS, THOUGH.

  1. #include <cstdio> 
  2.  
  3. void f() 
  4. { 
  5. int* arr = new int(1000); // OK 
  6.  
  7. ... 
  8.  
  9. arr = new int(1000); // LEAK !  
  10.  
  11. ... 
  12.  
  13. }  

.

  1. // this compiles fine but is very bad code 
  2. // protections of references are nullified by pointers 
  3.  
  4. void f() 
  5. { 
  6.  
  7. int* a = new int(1000); // OK but a is type int[1000]* 
  8. int* b = new int(1000); // OK but b is type int[1000]* 
  9. int* c; 
  10. int*& aref = a; // weirdly specific  
  11. aref = b; // LEAK  
  12. aref = new int(1000); // LEAK 
  13. aref = c; // BAD  
  14. }  

These are trivial but alas not unknown bonehead errors with pointers that you have to watch out for even in C++ code, not just C. Compare with C++ references.

  1. void array()  
  2. {  
  3. int a[10] ; // type is int[10]  
  4.  
  5. int b[10];  
  6.  
  7. int (&ar)[10] = a; // type is 'int[10] reference' 
  8.  
  9. auto& br = b; // c++11 simpler syntax  
  10.  
  11.  
  12. for( size_t i = 0 ; i < 10 ; i++) 
  13. {  
  14. ar[i] = i;  
  15. br[i]= -i;  
  16. } 
  17.  
  18. // ar = b; // ERROR: array type 'int [10]' is not assignable  
  19. // ar = br; // ERROR: array type 'int [10]' is not assignable  
  20.  
  21. }  

One place you can not get away from pointers is the use of arrays.
Array indexing with an integer index IS using pointer offsets into a chunk of memory, even if it is hidden in a sugary syntax.

  1. int arr[25]; 
  2. arr[22] = 5; // set 23rd slot of arr to 5 
  3. is actually 
  4.  
  5. *(arr + 22) = 5; 

and the compiler treats it that way when it creates the assembly code.

  1. int A[100][100]; 
  2. A[99][99] = 55; // row 99, col 99 
  3. is actually 
  4. *(A + (99 *100) + 99) = 55;  
  5.  
  6. int I[100]; 
  7. int J[100]; 
  8.  
  9. for ( int i ; i < 100 ; i++) 
  10. { 
  11. I[i] = i * i; 
  12. *(J + i) = *(I + i) + i; 
  13. } 
  14.  
  15. /* I[i] and *(I+i) are the same thing. */ 

Comments

Popular posts from this blog

proassignment help backlink data index 41

programming shark backink data index 31

Programming shark backlink data index 67