C++ - When to use pointers/references?

Started by
21 comments, last by Trienco 17 years, 10 months ago
I think the question in the topic mainly sums it up, but I think I also need to ask when should I create objects on the stack and the heap? If I understand correctly, I should use the heap for dynamic objects (short life) and the stack for static objects. I feel quite confident with most aspects of programming, but I think this is the main thing holding me back from experimenting with C++ more. Edit: Thought I should say I do know how to use pointers and references fine (certianly at the beginner level anyway) Any advice appriciated!
Ollie"It is better to ask some of the questions than to know all the answers." ~ James Thurber[ mdxinfo | An iridescent tentacle | Game design patterns ]
Advertisement
Actually quite simple, but so generic a question that I can't think of anything but examples. Let's take function calls:

func(const HugeObject& x) //good idea
func(HugeObject& x) //good idea, if side effects are _supposed_ to affect x
func(HugeObject x) //not so great, but chances are the compiler will optimize away
func(const int& x) //seriously pointless, int and pointer/reference are the same size
func(const char& x) //bordering on sillyness

More seriously: use pointers and references when they make sense. Prefer references, unless you know you will need to change what it points to later on. At the same time, don't desperately try to use them everywhere. Heap and stack is a question you usually don't have to ask yourself. You would never create an object on the heap with "new" if it's only needed within this one function.

More interesting dilemma would be a situation where you need to return a larger construct, but know it will only be used within the calling function. Construct on the heap and return a pointer (making it the responsibility of the calling function to clean it up again), or for example pass an empty object as reference and just fill it in (maybe with a bool return type to signal an error, where the other method would have returned a null pointer). Of course I wouldn't be surprised, if the compiler starts optimizing any potential difference away, anyway.
f@dzhttp://festini.device-zero.de
Cool, thank for those tips, Trienco! I had a feeling it was a "prefer references" case, but that's concreted it as to why (changing memory in the future cannot be done).
Ollie"It is better to ask some of the questions than to know all the answers." ~ James Thurber[ mdxinfo | An iridescent tentacle | Game design patterns ]
short answer:
references are best used when passing arguments (POD, struct, class, pointer) to a function.

pointers are best used when using data structures (stacks, queues, trees, graphs, linked lists, etc)

Beginner in Game Development?  Read here. And read here.

 

I assume the reason you want pointers with lists is because you are giving the responsibility to the list. Ie, delete the list - delete the pointers (If it's some type of custom list).
Ollie"It is better to ask some of the questions than to know all the answers." ~ James Thurber[ mdxinfo | An iridescent tentacle | Game design patterns ]
Here is my opinion since no one else has shared it yet:

Use pointers when a value should be able to have a null value, and references when it shouldn't. So if you are making a function and it CANNOT take a null argument use references. Otherwise use pointers. In the same way, if a function will ALWAYS return a valid object use references, otherwise use pointers so you can return null.

Since the main distinction (I believe) between the two is if they can be null, this system makes sense to me.
Turring Machines are better than C++ any day ^_~
Quote:Original post by acid2
I assume the reason you want pointers with lists is because you are giving the responsibility to the list. Ie, delete the list - delete the pointers (If it's some type of custom list).


References always point to the same thing, whereas pointer can be changed to move to other things. This makes it impossible to write containers using references.

As an consequence of this: Prefer to store pointers instead of references in classes/structs - else you won't be able to copy the class.
Use references when you can, and pointers when you have to

And I'd say taht the same rules could go for heap vs. stack: Use the stack when you can and the heap when you have to.

(and a third rule: follow the advice of programmers more experienced than I am)
First,

type& variable;
is analagous to
type*const variable;

second, references cannot legally be null.

Third, using reference variables looks like using a "real" variable.

Forth, references behave very differently when stored in a class or struct than pointers do. Never use a reference in a struct or class without knowing what you are doing -- and for spagetti's sake, think what happens when you copy-construct, swap or call operator=.

References are syntactic sugar. Sometimes you want syntactic sugar and sometimes you don't.
Quote:Original post by Nitage
As an consequence of this: Prefer to store pointers instead of references in classes/structs - else you won't be able to copy the class.


Why wouldn't you be able to do that? That's why god lets us write our own copy-constructor, so we can make sure all references are initialized in the init-list. Const members and references are behaving pretty much the same. It's not impossible, but you will have to pay a lot of attention when actually want the reference to point to a COPY of the original value in the other object. But generally the whole point of having a reference and not a direct member IS that you don't want each object having its own copy.

Prime example of a really stupid idea (on so many levels):
class Vector {public:  Coordinates& xyz;};


Unless of course, the reference is const and for whatever reason you only have a handful of coordinates, but a gazillion static objects using one of them. In that (somehow extremely unlikely) case it would probably pass as flyweight pattern.

More likely
class Object {  const TextureObject& texture;public:  Object(const TextureObject& t) : texture(t) {}};
f@dzhttp://festini.device-zero.de

This topic is closed to new replies.

Advertisement