C++ Pointers

Recommended Posts

Hmm, don't think I'm fully understanding pointers and their usefulness. Passing a pointer to a function so the actual variable gets updated...
void add_five(int *iNumber)
{
*iNumber += 5;
}

int iMy_number;

cout << iMy_number;

Understood. Faster array access through pointer arithmetic...
int iArray[10];
int *pArray_ptr;

pArray_ptr = iArray;

pArray_ptr++ = 1;  // no need for an array index variable
pArray_ptr++ = 2;

Position.draw();

Pointer Access...

Position->draw();

What are the benefits of accessing through a pointer?

Share on other sites
jamaicandude    124
i'm not that big of a C++ programmer but from what i understand it allows you to allocate objects on the heap/free store and the '->' notation is just how you access methods of that object.

Share on other sites
Trenki    345
For objects using the . or the -> notation is just a syntactic difference, nothing more. You use the object.method() if the object is allocated on the stack or if you hold a reference to the object while you have to write object->method() if object is actually a pointer. Thats basically all there is to it.

Share on other sites
Morrandir    304
Hi!

The examples you listed could be seen as minor usages for pointers.

The real thing comes into the picture with dynamic memory allocation - allocation of memory on the heap.

When you declare a variable, it will have memory allocated on the stack assigned. As soon as it goes out of scope (for example you leave the function it was declared in) it gets dumped.

When you declare a pointer, no memory gets allocated. It is up to you to allocate memory for the pointer using the new keyword, which allocates memory on the heap. This memory won't get dumped until you tell it to, using the delete keyword.

Lets see an example. A function that creates a new monster, an instance of the Monster class, which we want to further use in our program.

Without using dynamic allocation:
Monster createMonster(){  Monster m(/*parameters*/);  return m; // we try to keep our new monster from getting dumped, so we return it}

We have successfully kept the monster we created, however we had to copy him in order to do so (and we'll probably have to copy him again and again later on), which depending on the complexity of the Monster class could be a significant overhead.

With dynamic allocation:
Monster* createMonster(){  Monster* m = new Monster(/*parameters*/);  return m;}

We allocated our monster on the heap, so the only thing we have to return (and thus copy) is our pointer that points to his location in memory. We can pass around this pointer as we please, our monster won't get dumped. With power comes responsibility though: we have to remember to delete our monster when we don't need it anymore.

This came out a little long winded, but hope it sheds some light on the subject.

Share on other sites
kiome    229
{
*iNumber += 5;
}

That's a bad example since in C++ you have references for that case.

My tip is not to try forcing the usefulness of pointers onto you, but simply make sure you understand what they are, and how you can work on them.

You will, soon enough, find places where you have to use pointers, such as polymorphism or when your allocated objects have to outlive he scope they were created in.

Share on other sites
jeff75225    122
They are also useful in many data structures like linked lists and trees. If you are creating an array, and you don't know the number of elements before compile time, you will most likely have to use pointers.

Share on other sites
Ah, dynamic memory allocation. Thanks guys.

Morrandir, thanks for that good example (no copying required). And yes I will remember to delete afterwards - that's what destructors are for right? ;-)

Share on other sites
rip-off    10976
Quote:
 Original post by Steve ElliottAh, dynamic memory allocation. Thanks guys.Morrandir, thanks for that good example (no copying required). And yes I will remember to delete afterwards - that's what destructors are for right? ;-)

Thats what smart pointer objects are for.
#include <memory>std::auto_ptr<Monster> createMonster(){   return std::auto_ptr<Monster>(new Monster(/*parameters*/));}

It is well worth your while downloading the Boost libraries, you can think of them as add ons to the Standard C++ Library. In fact many of Boost's classes are considered for the upcoming C++0x standard. It includes a number of smart pointer implementations with more natural copy semantics than std::auto_ptr<>.

Share on other sites
ExcessNeo    619
Quote:
 Original post by Steve ElliottAh, dynamic memory allocation. Thanks guys.Morrandir, thanks for that good example (no copying required). And yes I will remember to delete afterwards - that's what destructors are for right? ;-)

It can be a use for destructor if you create a class to manage a resource.

Share on other sites
Ok, I've got what I wanted now for the Position Class - any errors here?

csPosition* Position = NULL;Position = Position->create();Position->reset();Position->draw();csPosition* csPosition::create(){    csPosition* Position = new csPosition;    return Position;}

Share on other sites
Ezbez    1164
1. Why do you need pointers here? Why does memory need to be on the heap?
2. Could I use references instead?
3. How about just having it on the stack?
4. Why do I need a create function? Using new is idiomatic and expected in C++, do I have a need for something else?
5. Does the drawing of a position belong in the Position class? Does this tie the position class to the renderer that you're using?
6. Why is there no name for the variable that's being declared on your second line?!?! (Joking! I know that it's just a careless mistake.)

Share on other sites
kiome    229
Quote:
 Original post by Steve ElliottOk, I've got what I wanted now for the Position Class - any errors here?csPosition* Position = NULL;Position = Position->create();Position->reset();Position->draw();csPosition* csPosition::create(){ csPosition* Position = new csPosition; return Position;}

That's what you get for trying to apply something you don't need yet ;).
Ezbez already pointed out that your intention in this example is unclear, as to why you need to have that object on free-store. Without seeing the context we can not certainly tell you if your example is good.

Another point would be your naming convention. You are generally free to choose your own naming scheme, though there are some generally accepted conventions on certain things: class names should start with a capital letter, in C++ there is no need to have any class prefix (like c or in your case cs).

A better way to put your example would be (assuming it really should be on the free-store rather than heap space):

Position* somePosition = new Position();
...

There is no need for a "create" method since this is what the constructor of the class is responsible for.
Besides that, by calling your create() method from a null-pointer you've set yourself in the world of unknown behaviour by the C++ standard. It may (it will most probably, since your method does not access any member variables) work, but it doesn't have to, so never do that again.

Share on other sites
Andorien    139
If you're dead set on having a create function in your class (which, as someone pointed out, isn't necessary), a better way to do it would be to use a static method.

You would do it like this:
csPosition* Position = NULL;Position = csPosition::create(); // Notice we access the static method through the class, not a pointer or an instance;Position->reset();Position->draw();static csPosition* csPosition::create() // Static methods are associated with a class rather than an instance.  Their only limitation is that they can't access non-static methods or variables.{    csPosition* Position = new csPosition;    return Position;}