Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class members that are objects - Pointers or not? C++

If I create a class MyClass and it has some private member say MyOtherClass, is it better to make MyOtherClass a pointer or not? What does it mean also to have it as not a pointer in terms of where it is stored in memory? Will the object be created when the class is created?

I noticed that the examples in QT usually declare class members as pointers when they are classes.

like image 333
Mark Avatar asked Oct 06 '10 10:10

Mark


People also ask

Can a class object be a pointer?

A pointer to a C++ class is done exactly the same way as a pointer to a structure and to access members of a pointer to a class you use the member access operator -> operator, just as you do with pointers to structures. Also as with all pointers, you must initialize the pointer before using it.

Are all objects pointers?

Objects themselves aren't pointers, they're areas of memory with data in them.

Are objects just pointers?

In java and objective-c, a variable representing an object is generally a pointer to that object. However, it seems that in C++, it's common to have non-pointer types hold objects.

Is object member of class?

An object is a member or an "instance" of a class. An object has a state in which all of its properties have values that you either explicitly define or that are defined by default settings.


2 Answers

If I create a class MyClass and it has some private member say MyOtherClass, is it better to make MyOtherClass a pointer or not?

you should generally declare it as a value in your class. it will be local, there will be less chance for errors, fewer allocations -- ultimately fewer things that could go wrong, and the compiler can always know it is there at a specified offset so... it helps optimization and binary reduction at a few levels. there will be a few cases where you know you'll have to deal with pointer (i.e. polymorphic, shared, requires reallocation), it is typically best to use a pointer only when necessary - especially when it is private/encapsulated.

What does it mean also to have it as not a pointer in terms of where it is stored in memory?

its address will be close to (or equal to) this -- gcc (for example) has some advanced options to dump class data (sizes, vtables, offsets)

Will the object be created when the class is created?

yes - the size of MyClass will grow by sizeof(MyOtherClass), or more if the compiler realigns it (e.g. to its natural alignment)

like image 146
justin Avatar answered Sep 24 '22 23:09

justin


Where is your member stored in memory?

Take a look at this example:

struct Foo { int m; }; struct A {   Foo foo; }; struct B {   Foo *foo;   B() : foo(new Foo()) { } // ctor: allocate Foo on heap   ~B() { delete foo; } // dtor: Don't forget this! };  void bar() {   A a_stack; // a_stack is on stack              // a_stack.foo is on stack too   A* a_heap = new A(); // a_heap is on stack (it's a pointer)                        // *a_heap (the pointee) is on heap                        // a_heap->foo is on heap   B b_stack; // b_stack is on stack              // b_stack.foo is on stack              // *b_stack.foo is on heap   B* b_heap = new B(); // b_heap is on stack                        // *b_heap is on heap                        // b_heap->foo is on heap                        // *(b_heap->foo is on heap   delete a_heap;   delete b_heap;   // B::~B() will delete b_heap->foo! }  

We define two classes A and B. A stores a public member foo of type Foo. B has a member foo of type pointer to Foo.

What's the situation for A:

  • If you create a variable a_stack of type A on the stack, then the object (obviously) and its members are on the stack too.
  • If you create a pointer to A like a_heap in the above example, just the pointer variable is on the stack; everything else (the object and it's members) are on the heap.

What does the situation look like in case of B:

  • you create B on the stack: then both the object and its member foo are on the stack, but the object that foo points to (the pointee) is on the heap. In short: b_stack.foo (the pointer) is on the stack, but *b_stack.foo the (pointee) is on the heap.
  • you create a pointer to B named b_heap: b_heap (the pointer) is on the stack, *b_heap (the pointee) is on the heap, as well as the member b_heap->foo and *b_heap->foo.

Will the object be automagically created?

  • In case of A: Yes, foo will automatically be created by calling the implicit default constructor of Foo. This will create an integer but will not intitialize it (it will have a random number)!
  • In case of B: If you omit our ctor and dtor then foo (the pointer) will also be created and initialized with a random number which means that it will point to a random location on the heap. But note, that the pointer exists! Note also, that the implicit default constructor won't allocate something for foo for you, you have to do this explicitly. That's why you usually need an explicit constructor and a accompanying destructor to allocate and delete the pointee of your member pointer. Don't forget about copy semantics: what happens to the pointee if your copy the object (via copy construction or assignment)?

What's the point of all of this?

There are several use cases of using a pointer to a member:

  • To point to an object you don't own. Let's say your class needs access to a huge data structure that is very costly to copy. Then you could just save a pointer to this data structure. Be aware that in this case creation and deletion of the data structure is out of the scope of your class. Someone other has to take care.
  • Increasing compilation time, since in your header file the pointee does not have to be defined.
  • A bit more advanced; When your class has a pointer to another class that stores all private members, the "Pimpl idiom": http://c2.com/cgi/wiki?PimplIdiom, take also a look at Sutter, H. (2000): Exceptional C++, p. 99--119
  • And some others, look at the other answers

Advice

Take extra care if your members are pointers and you own them. You have to write proper constructors, destructors and think about copy constructors and assignment operators. What happens to the pointee if you copy the object? Usually you will have to copy construct the pointee as well!

like image 26
WolfgangP Avatar answered Sep 24 '22 23:09

WolfgangP