tags:

views:

267

answers:

8

I'm coming from Java and attempting to learn C++.

As far as I can tell, using Pointers is very similar to how reference variables work in Java, in that you pass a memory address to the value. So I feel like I have gotten a pretty good understanding of them. I also understand that these variables are stored on the heap.

However, I see that there is another way in which you can declare variables in C++, without the new operator/pointers simply doing something like:

Employee boss("Frank");

Which will create a value of Employee with "Frank" as the parameter. These variables are stored on the stack.

So, you have these 2 very different ways of creating variables and both with their own unique behavior (with memory management as well?).

My question is, when is it appropriate to use pointers VS values? What is the best practice? How should I know in what way I want to declare my variables most of the time?

A: 

Two different beasts: if you assign by pointer, you end-up with n-to-1 relationships which you must handle through proper resource management. This is normally taken care of in Java.

In what you call "Reference Objects", you get different objects (which need to be tracked etc.).

jldupont
What do you call "Reference Objects", so I know the proper terminology? I didn't know so I just made something up.
Mithrax
+2  A: 

There are two different issues at play here: Creating objects, and referring to them.

Creating

There are two places that objects are created: the stack and the heap. If you use the syntax you described:

Employee boss("Frank");

Will create it on the stack. If you write this:

Employee* boss = new Employee("Frank");

It will create it on the heap. If you're not familiar with the concepts of stack and heap, it is vitally important to being a good C++ coder, so learn about it!

Referring

Referring to objects is somewhat different. Regardless of how an object is created, it can be referred to using a pointer or a reference (or just a standard variable). Using references and pointers in C/C++ is actually very much the same thing, though there are important differences.

When using pointers or references, a copy of the object is not made.

// No copies made:
Employee& frank = boss;  // Using References
Employee* frank = &boss; // Using a Pointer

A copy is made when you use neither.

// Copy is made:
Employee frank = boss;

So when would you use pointers, and when would you use references? I find that a good practise is to only use pointers when it is meaningful for it to be null. If something should not be null, make it a reference.

Smashery
+1  A: 

The C++ FAQ has a good answer to this specific question:

http://www.parashift.com/c++-faq-lite/references.html#faq-8.6

James Farrell
Not really; his background in Java is causing some terminology confusion. He's not asking about pointers vs references, but pointers vs stack-allocated values.
John Millikin
+1  A: 

Generally you want to stick with references as much as possible. The reason is because of RAII. Basically, this guarantees no memory leaks if you are using RAII.

However, IMO you should use pointers when the objects you are using would be very expensive to copy. Passing around container types will cause duplicates of the containers to occur... not a great idea.

The best way is to use smart pointers... basically references which hold a pointer and keep track of the number of references to the pointer. This is really the best of both worlds... Cheap initialization/copies and reference counting to practically eliminate memory leaks.

Polaris878
+3  A: 

C++ pointers operate exactly like Java objects, in that they may be invalid (NULL) and are cheap to pass to procedures.

C++ references are a thin wrapper around pointers. They're not supposed to be invalid, but in some cases may be. For example, a reference might be created from a NULL pointer, or the memory it references might be deleted.

In the code example you give:

Employee boss("Frank");

you are using something called a "value". Unlike pointers and references, values are the object they represent, not an indirection.

My question is, when is it appropriate to use Pointers VS [values]? What is the best practice? How should I know in what way I want to declare my variables most of the time?

C++ doesn't have garbage collection, so values are used when the scope of a variable is limited. For example, instead of allocating one with new and deallocating with delete for every variable in a procedure, you can allocate them on the stack and not worry about the memory.

John Millikin
+1  A: 

Note: I will use "object" to refer to objects and to primitive types such as int, float... these are not the same in C++ (but usually you can ignore this).

Use values when you are creating an object that you control from that scope, and it should die when that scope ends. Also, use value when you want to use a copy of an external object, but you only want to handle the copy not the real object. Example:

int myFunction(int external_value1, Object external_value2){
    ---
}

Use pointers/references when you are creating an Object that should not die when it's scope of creation ends (ensure to pass a pointer to it to some other scope!), or when using an external value that is expensive to copy (like a container), or when you want to operate directly on that external object and not on a copy of it. That's why I/O parameters of functions are usually pointers or references, as you want to act on an external object (defined outside of the scope of the function) directly and not on a local copy. Example:

int myOtherFunction(int *external_value1, Object *external_value2{
    ---
}

In this example, if you operate on the value pointed by the parameters, you are affecting exactly that: the value those pointers point at, thus changing a variable outside of the function scope. In fact is a pass-by-value, but you are copying only the pointers, and using them to "attack" the external values.

References are, as stated by other post, just syntactic sugar for pointers. Once you understand pointers, you understand references ;).

machielo
A: 

If you are programming in a restricted environment (embedded, etc...) where memory and processor power are kind of shortage it's better for you to use pointers (or references). Generally speaking, always pass in a (const) reference to a function if it needs an object of any kind. Make it const if you don't want to modify the object. Don't waste time and space by creating and destructing and object.

For some projects I personally preferred pointers exactly because of the syntax difference. When passing by reference there's not too much difference in how you user your parameters compared to the pass by value approach, so actually there might come small mistakes (especially if there are more people working on the same project), when you forget to put an & in the function declaration, and an objects gets constructed/destructed on the stack totally unnecessarily.

Use reference counted smart pointers (boost:shared_ptr for example) if you are unsure about the life-cycle of your objects, especially if they are shared between various modules, or you need to store pointer elements in STL containers. Don't write your own smart pointer classes, there are a lot of very good implementations out there.

fritzone