tags:

views:

627

answers:

4

One of the thing that has been confusing for me while learning C++ (and Direct3D, but that some time ago) is when you should use a pointer member in a class. For example, I can use a non-pointer declaration:

private:
    SomeClass instance_;

Or I could use a pointer declaration

private:
   Someclass * instance_

And then use new() on it in the constructor.

I understand that if SomeClass could be derived from another class, a COM object or is an ABC then it should be a pointer. Are there any other guidelines that I should be aware of?

+8  A: 

Allocate it on the stack if you can, from the free-store if you have to. There is a similar question here, where you will find all the "why's".

The reason you see lots of pointer usage when it comes to games and stuff is because DirectX is a COM interface, and in honesty, most games programmers from back in the day aren't really C++ programmers, they are C-with-classes programmers, and in C pointer usage is very common.

GMan
+7  A: 

A pointer has following advantages:

a) You can do a lazy initialization, that means to init / create the object only short before the first real usage.

b) The design: if you use pointers for members of an external class type, you can place a forward declaration above your class and thus don't need to include the headers of that types in your header - instead of that you include the third party headers in your .cpp - that has the advantage to reduce the compile time and prevents side effects by including too many other headers.

class ExtCamera;  // forward declaration to external class type in "ExtCamera.h"

class MyCamera {
public: 
  MyCamera() : m_pCamera(0) { }

  void init(const ExtCamera &cam);

private:
   ExtCamera  *m_pCamera;   // do not use it in inline code inside header!
};

c) A pointer can be deleted anytime - so you have more control about the livetime and can re-create an object - for example in case of a failure.

3DH
For lazy initialization, I would recommend using `boost::optional` whenever possible. It's safer than pointer because you can't do arithmetic on it.
Pavel Minaev
But many (like me) don't use Boost - so this is a very platform and framework independent way ;-) ...I for example only use Qt :-)
3DH
But those that don't use `boost` should :)
GMan
Extrakun
Forward declaring *should* work for references.
GMan
Forward declarations _do_ work for references.
Dima
I guess I will ask that question another time; for some reason it does not work for me...
Extrakun
I'm worried you accepted this. Not about rep, but that it *is* better to try and not to use pointers.
GMan
@Extrakun, make sure you are not trying to access any members of QPoint anywhere in that header file.
Dima
I wish I can accept more than one answer, because some of the post do contain reasons why I shouldn't use pointer members, but this one does at least explain the reason for pointer members.
Extrakun
You still can use forward declarations together with references - as far as you dont have any code in your header, which _uses_ (accesses) the references - so any declarations work, but not inline code.
3DH
I managed to get forward declaration for reference working. I must have tried to access it somewhere in the .h file which is why it causing error. Thanks!
Extrakun
These are both silly reasons to use pointers in a class. Please de-select this as the best answer.
Martin York
Hi Martin, my intent is to find out 'when', not 'shouuld'. Naked pointers are of course dangerous. I will bear in the mind the risk of using naked pointers as members in a class.
Extrakun
@Martin: Your comment is not a perfect example of professional thinkink and acting. There are pros and contras - and the word is not just white and black. A professional developer should have the choice to use both methods and should know, why and why not.
3DH
+7  A: 

The advantages of using a pointer are outlined by 3DH: lazy initialization, reduction in header dependencies, and control over the lifetime of the object.

The are also disadvantages. When you have a pointer data member, you probably have to write your own copy constructor and assignment operator, to make sure that a copy of the object is created properly. Of course, you also must remember to delete the object in the destructor. Also, if you add a pointer data member to an existing class, you must remember to update the copy constructor and operator=. In short, having a pointer data member is more work for you.

Another disadvantage is really the flip side of the control over the lifetime of the object pointed to by the pointer. Non-pointer data members are destroyed automagically when the object is destroyed, meaning that you can always be sure that they exist as long as the object exists. With the pointer, you have to check for it being NULL, meaning also that you have to make sure to set it to NULL whenever it doesn't point to anything. Having to deal with all this may easily lead to bugs.

Finally, accessing non-pointer members is likely to be faster, because they are contiguous in memory. On the other hand, accessing pointer data member pointing to an object allocated on the heap is likely to cause a cache miss, making it slower.

There is no single answer to your question. You have to look at your design, and decide whether the advantages of pointer data members outweigh the additional headache. If reducing compile time and header dependencies is important, use the pimpl idiom. If your data member may not be necessary for your object in certain cases, use a pointer, and allocate it when needed. If these do not sound like compelling reasons, and you do not want to do extra work, then do not use a pointer.

Dima
+3  A: 

Another reason to use pointers would be dynamic binding. If you have a base class with a virtual method and some derived classes, you can only get dynamic binding using pointers.

jradakov
That's not quite right - you can have dynamic binding with references.
boxofrats
Very true, thank you for the clarification.
jradakov