0

What are the differences between declaring a variable in a header file as pointer or non-pointer? I am not sure if I understand the differences correctly.

E.g.

class MyClass {

private:
    MyOtherClass* moc; // pointer
    MyOtherClass moc2; // no pointer
}

So far I have come up with the following advantages/disadvantages when declaring a variable as pointer.

Advantages:

  • Lazy instantiation (no immediate creation of the object)
  • Variable lives on the heap which is much larger than the stack
  • Not only the default constructor can be used

Disadvantages:

  • Must be deleted manually in the destructor (btw. when is such a non-pointer variable destructed? When the program ends?)

What else is there to say?

telandor
  • 869
  • 9
  • 28
  • 5
    The other issue is that you will need the full definition of MyOtherClass in your header if not a pointer whilst you can forward declare the class if its a pointer and include the header in the cpp – EdChum Aug 07 '14 at 09:12
  • 3
    You can use other constructors than the default constructor via initialization lists. You can use smart pointers in order to get rid of the destructor, although a well-written class implementation won't need those. – Zeta Aug 07 '14 at 09:13
  • 3
    Variable lives on the heap? Which variable? You haven't shown anything where something gets allocated on the "heap". All you have is a data member that is a pointer, and that could point to anything (or nothing.) – juanchopanza Aug 07 '14 at 09:20
  • 1
    In your list of advantages, the second and third bullets are not correct. – barak manos Aug 07 '14 at 09:24

3 Answers3

5

Having an object signifies ownership. It's composition. Pointers can signify ownership, but most of the time they mean aggregation.

I.e. MyClass has a moc2 and uses moc.

Take your decision thinking about the design of the classes and how they interact with each other, not based on the pointer vs. object debate. Each MyClass object will have its own moc2 member, but multiple MyClass objects can share a moc between them.

Regarding your proposed advantages/disadvantages:

Advantages:

  • Lazy instantiation (no immediate creation of the object) - the pointer itself is initialized - remember your member is a pointer not an object. But I'll give you that you sometimes need this, although it's most of the time a code-smell.
  • Variable lives on the heap which is much larger than the stack - not necessarily - you can have a pointer to a stack-based variable as well. Also, if a MyClass object is allocated on the heap, so will moc2.
  • Not only the default constructor can be used - non-issue, you can use any constructor in both cases (see initialization-lists).

Disadvantages:

  • Must be deleted manually in the destructor (btw. when is such a non-pointer variable destructed? When the program ends?) - only if MyClass owns the member - it could be a pointer to some object created elsewhere, so MyClass isn't responsible for managing it.
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Just to add a point here: in the case `MyClass` is the owner you can use `std::unique_ptr` to avoid the manual destruction of the object. – cbuchart Feb 27 '17 at 22:50
1

Some of the advantages/disadvantages need correction, so here you go:

Advantages: - Lazy instantiation (no immediate creation of the object) - No need for the definition of the class to be visible, forward declaration suffices

Disadvantages: - Must be deleted manually in the destructor - You need to manually declare all copy constructors and assignment operators - more complicated access (-> instead of .)

Some alternatives: smart pointer (std::unique_ptr). Has all advantages of the raw pointer and no need for explicit delete in the destructor, generally is much safer. Raw pointers should never be used unless really necessary, so if you need advantages of the pointer, use smart one.

And if you want lazy initialisation boost::optional may be used.

And in the end comments to your list:

Variable lives on the heap which is much larger than the stack

Not entirely true. If it is a pointer and object is created with new, the object will be in the heap. Otherwise it won't necessarily be on the stack. It will be where the parent object is. If the parent object is on the heap, the enclosed object - begin part of it - is on the heap also.

Not only the default constructor can be used

Not true at all, will initialisation list you can specify any arguments for member constructor.

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
0

Having a pointer does not automatically mean that you will have dynamically allocated variables. You can very much have a pointer to automatic or static variables as well (I'm not saying this is common or encouraged, I'm just being technical). Having a pointer gives you the option of allocating variables dynamically, but the downside is you have to manage the memory yourself, (See here and here).

As for when to use either, this has already been discussed on SO here

One difference that comes to mind is in header inclusions. When you have a pointer to an instance as a member, then you are permitted to forward-declare that type, whereas including it by value means that you have to include the header, which slows down build times.

Community
  • 1
  • 1
Nasser Al-Shawwa
  • 3,573
  • 17
  • 27