16

After reading some tutorials I came to the conclusion that one should always use pointers for objects. But I have also seen a few exceptions while reading some QT tutorials (http://zetcode.com/gui/qt4/painting/) where QPaint object is created on the stack. So now I am confused. When should I use pointers?

Jan Bodnar
  • 10,969
  • 6
  • 68
  • 77
Jamol
  • 2,281
  • 2
  • 28
  • 28
  • The QT tutorials create the QPaint object on the stack because the QPaint object's useful life is known at compile time and is exactly bounded by a matched pair of {}. – Thomas L Holaday Mar 19 '09 at 05:58
  • The same is holds for QPen, QPainter, and QApplication. – Thomas L Holaday Mar 19 '09 at 06:01
  • What is great to know about pointer is that we now have in C++ some safe implementation of pointers like unique_ptr or weak_ptr, when you need to use pointer, you need to use them (with some rare exception on low level code) – MokaT Jul 20 '15 at 13:33

14 Answers14

42

If you don't know when you should use pointers just don't use them.

It will become apparent when you need to use them, every situation is different. It is not easy to sum up concisely when they should be used. Do not get into the habit of 'always using pointers for objects', that is certainly bad advice.

CiscoIPPhone
  • 9,457
  • 3
  • 38
  • 42
  • 6
    This isn't an answer. The point of this site is to help people learn more, not to dismiss them when you can't articulate your thoughts. – A.R. Mar 13 '14 at 02:09
  • @A.R. Hopefully I did let jamolkhon learn not to always use pointers - look at the first sentence to his question. I took that context into account, not just the title. Besides, other questions list some of the uses. – CiscoIPPhone Mar 13 '14 at 20:46
  • I took the last sentence into account, you know, the question part. – A.R. Mar 14 '14 at 00:05
  • 1
    @A.R. So did I. But taking context into account can help you create an answer which is more useful than just looking at the sentence which contains the question - especially if other people have already addressed that. – CiscoIPPhone Mar 14 '14 at 00:38
  • Yeah I learned a lot from your very useful answer. Now I am an expert on when and when not to use pointers. I especially like how you cross reference your breadth of knowledge on the topic of pointers with other "people who have already addressed that" by providing links. Amazing! – A.R. Mar 14 '14 at 01:21
  • 1
    @A.R. There's no need to be snarky. Other people felt my answer was helpful, if you don't that is fine, just downvote and move on. – CiscoIPPhone Mar 14 '14 at 01:26
  • Who's being snarky? This answer is so useful that I can actually apply it to any question I would ever have about anything: If I don't know how to use it, then I should not use it, and then by not using it or knowing how to use it, it will become apparent when and how it should be used! PURE GENIUS! My only wish is that I could upvote TWICE! – A.R. Mar 14 '14 at 14:39
  • 1
    @A.R. OP came to the conclusion that he should always use pointers, I feel my answer is helpful for this specific case. I've seen this many times, even in professional code bases where people use pointers when there is no need. My advice is don't use them always, and for the cases you do need them it will become apparent. It can't be applied to all questions - perhaps only the ones where people have come to the conclusion that something should always be used that can actually be detrimental. – CiscoIPPhone Mar 14 '14 at 15:33
21

Main reasons for using pointers:

  1. control object lifetime;
  2. can't use references (e.g. you want to store something non-copyable in vector);
  3. you should pass pointer to some third party function;
  4. maybe some optimization reasons, but I'm not sure.
strager
  • 88,763
  • 26
  • 134
  • 176
bayda
  • 13,365
  • 8
  • 39
  • 48
15

It's not clear to me if your question is ptr-to-obj vs stack-based-obj or ptr-to-obj vs reference-to-obj. There are also uses that don't fall into either category.

Regarding vs stack, that seems to already be covered above. Several reasons, most obvious is lifetime of object.

Regarding vs references, always strive to use references, but there are things you can do only with ptrs, for example (there are many uses):

  • walking through elements in an array (e.g., marching over a standard array[])
  • when a called function allocates something & returns it via a ptr

Most importantly, pointers (and references, as opposed to automatic/stack-based & static objects) support polymorphism. A pointer to a base class may actually point to a derived class. This is fundamental to the OO behavior supported in C++.

Dan
  • 10,303
  • 5
  • 36
  • 53
  • 3
    +1 for the last, bolded, paragraph, because I can't upvote it more myself. – David Thornley Mar 18 '09 at 15:11
  • But you can allocate something on the stack and then use it later polymorphically by passing a reference or pointer to your function/container/whatever. **Storage duration and polymorphism are orthogonal concepts.** Yet people continue to answer questions about why one might allocate via pointer by citing polymorphism as an advantage, without ever explaining why the two are related (they're not). – underscore_d Jul 09 '16 at 09:47
10

First off, the question is wrong: the dilemma is not between pointers and stack, but between heap and stack. You can have an object on the stack and pass the pointer to that object. I assume what you are really asking is whether you should declare a pointer to class or an instance of class.

The answer is that it depends on what you want to do with the object. If the object has to exist after the control leaves the function, then you have to use a pointer and create the object on heap. You will do this, for example, when your function has to return the pointer to the created object or add the object to a list that was created before calling your function.

On the other hand, if the objects is local to the function, then it is better to use it on stack. This enables the compiler to call the destructor when the control leaves the function.

ajanicij
  • 415
  • 3
  • 12
4

Which tutorials would those be? Actually, the rule is that you should use pointers only when you absolutely have to, which is quite rarely. You need to read a good book on C++, like Accelerated C++ by Koenig & Moo.

Edit: To clarify a bit - two instances where you would not use a pointer (string is being used here as an exemplar - same would go for any other type):

class Person {
   public:
      string name;       // NOT string * name;
   ...
};


void f() {
   string value;        // NOT string * value
   // use vvalue
}
  • How about the limitations of stack? – Jamol Mar 18 '09 at 13:00
  • what limitation would that be? –  Mar 18 '09 at 13:01
  • well i mean on some systems if not all the size of the stack is limited isn't it? – Jamol Mar 18 '09 at 13:04
  • @presario: the stack size is limited, but for the normal reasons you do not have to use pointers for this case – Ahmed Mar 18 '09 at 13:10
  • Pointers are a tool. Limiting their use to "only when you absolutely have to" is too strict. With proper design considerations, they can be a key to a very maintainable and robust design. – Nate Mar 18 '09 at 13:46
  • @nate nobody is suggesting otherwise –  Mar 18 '09 at 13:47
  • In 15 years I don't think I've ever run out of stack that wasn't something like a stupid recursion bug. – Rob K Mar 18 '09 at 21:20
4

You usually have to use pointers in the following scenarios:

  1. You need a collection of objects that belong to different classes (in most cases they will have a common base).

  2. You need a stack-allocated collection of objects so large that it'll likely cause stack overflow.

  3. You need a data structure that can rearrange objects quickly - like a linked list, tree ar similar.

  4. You need some complex logic of lifetime management for your object.

  5. You need a data structure that allows for direct navigation from object to object - like a linked list, tree or any other graph.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • In the case of (1) there is no "perhaps" about the need for a common base. In the case of (2) the only "collection" where this would apply would be a C-style array. –  Mar 18 '09 at 14:39
  • For case (1) it's not necessary, you may want to store an array of void* to be able to just call free() - that's not C++ way of doing things, but might be. For case (2) I meant an array of pointers versus an array of actual objects. If objects are really large storing pointers save much stack space. – sharptooth Mar 19 '09 at 04:55
2

In addition to points others make (esp. w.r.t. controlling the object lifetime), if you need to handle NULL objects, you should use pointers, not references. It's possible to create a NULL reference through typecasting, but it's generally a bad idea.

Mr Fooz
  • 109,094
  • 6
  • 73
  • 101
1

If possible never use pointers. Rely on pass by reference or if you are going to return a structure or class, assume that your compiler has return value optimization. (You have to avoid conditional construction of the returned class however).

There is a reason why Java doesn't have pointers. C++ doesn't need them either. If you avoid their use you will get the added benefit of automatic object destruction when the object leaves scope. Otherwise your code will be generating memory errors of various types. Memory leaks can be very tricky to find and often occur in C++ due to unhandled exceptions.

If you must use pointers, consider some of the smart pointer classes like auto_ptr. Auto destruction of objects is more than just releasing the underlying memory. There is a concept called RAII. Some objects require additionally handing on destruction. e.g. mutexes and closing files etc.

Matt
  • 27
  • 1
  • 1
    Well, Java doesn't "have" pointers because everything other than a primitive is implicitly a pointer. – mk12 Aug 19 '13 at 00:18
1

Generally use pointers / references to objects when:

  • passing them to other methods

  • creating a large array (I'm not sure what the normal stack size is)

Use the stack when:

  • You are creating an object that lives and dies within the method

  • The object is the size of a CPU register or smaller

LegendLength
  • 473
  • 3
  • 11
  • So both of you: pass objects on the stack, create large arrays on the stack, allocate local variables on the heap, allocate integers on the heap? – LegendLength Mar 18 '09 at 22:23
1

I actually use pointers in this situation:

class Foo
{
    Bar* bar;

    Foo(Bar& bar) : bar(&bar) { }

    Bar& Bar() const { return *bar; }
};

Before that, I used reference members, initialized from the constructor, but the compiler has a problem creating copy constructors, assignment operators, and the lot.

Dave

Dave Van den Eynde
  • 17,020
  • 7
  • 59
  • 90
1

using pointers is connected with two orthogonal things:

  1. Dynamic allocation. In general, you should allocate dynamically, when the object is intended to live longer that the scope in which it's created. Such an object is a resource which owner have to be clearly specified (most commonly some sort of smart pointer).

  2. Accessing by address (regardless of how the object was created). In this context pointer doesn't mean ownership. Such accessing could be needed when:

    • some already existing interface requires that.
    • association which could be null should be modeled.
    • copying of large objects should be avoided or copying is impossible at all, but the reference can't be used (e.g., stl collections).

The #1 and #2 can occur in different configurations, for example you can imagine dynamically allocated object accessed by pointer, but such the object could also by passed by reference to some function. You also can get pointer to some object which is created on the stack, etc.

oo_olo_oo
  • 2,815
  • 5
  • 28
  • 25
  • "two orthogonal things" - finally, someone said it! [c.f.](http://stackoverflow.com/questions/658133/c-when-to-use-pointers#comment63979527_658308) I would add to point **2** that accessing by reference/pointer (=address) enables polymorphism, regardless of how the object was allocated - contrary to the baffling number of posts I see implying that a valid reason for dynamic allocation is to grant polymorphic behaviour - which is not required, not an argument, and completely unrelated. – underscore_d Jul 09 '16 at 09:52
1

Pass by value with well behaved copyable objects is the way to go for a large amount of your code.

If speed really matters, use pass by reference where you can, and finally use pointers.

dicroce
  • 45,396
  • 28
  • 101
  • 140
0

Use pointers when you don't want your object to be destroyed when the stack frame is emptied.

Use references for passing parameters where possible.

Mark Ingram
  • 71,849
  • 51
  • 176
  • 230
  • int x; int* pointer_to_x = &x; You're repeating the OP's confusion between pointers and heap allocation. – Pete Kirkham Mar 18 '09 at 13:17
  • No, passing by const reference instead of value is a good habit to get into. While it uses pointers on the implementation level, it has nothing to do with them conceptually. – David Thornley Mar 18 '09 at 15:10
0

Speaking about C++, objects created on the stack cannot be used when the program has left the scope it was created in. So generally, when you know you don't need a variable past a function or past a close brace, you can create it on the stack.

Speaking about Qt specifically, Qt helps the programmer by handling a lot of the memory management of heap objects. For objects that are derived from QObject (almost all classes prefixed by "Q" are), constructors take an optional parameter parent. The parent then owns the object, and when the parent is deleted, all owned objects are deleted as well. In essence, the responsibility of the children's destruction is passed to the parent object. When using this mechanism, child QObjects must be created on the heap.

In short, in Qt you can easily create objects on the heap, and as long as you set a proper parent, you'll only have to worry about destroying the parent. In general C++, however, you'll need to remember to destroy heap objects, or use smart pointers.

swongu
  • 2,229
  • 3
  • 19
  • 24