1

I apologize in advance as I'm not after a specific answer as such. Just some insight would be appreciated. The comments (along with the code) below, outline some observations, clarifications, and uncertainties. The issue here is really lifetime of members.

class SomeClass {
 int m_int; // primitive type. hardly ever see a pointer

 // For class instances, you always* seem to see this
 SomeOtherClass* m_some_other_class_instance_1;
 // and not this
 SomeOtherClass m_some_other_class_instance_2;

 // But lately, I've noticed that for std:: templates, it doesn't seem to be this
 vector<double>* m_vector_instance_1;
 // but rather this
 vector<double> m_vector_instance_2;
};

// So it got me thinking ...


void mainThread() {
  SomeClass* some_class_instance_1 = new SomeClass();
  // SomeClass instance on heap
  // So all its members (both <xx>_1 and <xx>_2) are on heap as well
  // Hence all its members will stay alive beyond the scope of this function (or do they?)

  SomeClass some_class_instance_2;
  // SomeClass instance on stack
  // So the only piece of data relating to SomeClass that's on the heap is what's pointed to by <xx>_1 members
  // But everything else will still stay alive within the scope of this function

  // In conclusion, using either case above, members of a SomeClass instance stay alive for their intended period
  // So are <xx>_1 members overkill?

  // Ah, ha, ha, ha, stayin' alive, stayin' alive ...
}

In terms of context, let's assume that SomeClass is not aware of any other classes around it and doesn't expect to be passing anything in/out for now...so the constructor might just initialise its members with whatever and the person who wrote it has no idea of how the class may be used. The only concern is the members staying alive.

I've read through these threads but they aren't quite related:

Why should I use a pointer rather than the object itself?

Class members and explicit stack/heap allocation

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

Community
  • 1
  • 1
Ash
  • 1,618
  • 2
  • 15
  • 42
  • Do you have a question? – R Sahu Jun 04 '15 at 05:19
  • Read the comments within the code. Some of them are questions. – Ash Jun 04 '15 at 05:20
  • How about something a little more clear and concrete than *"So are _1 members overkill?"* – Benjamin Lindley Jun 04 '15 at 05:22
  • What's there is indeed very clear...but for further clarity...do I need pointers to heap or will stack members give me the same level of integrity in terms of lifetime? – Ash Jun 04 '15 at 05:24
  • heap life time is determined by the programmer. Stack is determined by the scope. If the programmer chooses to link the heap allocation to scope then the life time will be the same. But if you lose your pointer to your heap allocation it will still exist in memory and you can't use that memory again. You have a leak. This should be avoided. –  Jun 04 '15 at 08:11
  • 1
    Main reasons for heap allocation off the top of my head. Ownership, sharing an object across other objects `shared_ptr`, Polymorphism, Memory pools for very fast allocations, delaying the loading `init()` style methods`, avoiding stackoverflows in heavy recursive functions, and Arrays. –  Jun 04 '15 at 08:17
  • @PhilCK All of which seem like legitimate reasons for heap allocation....but not member lifetime right? That very much seems like the responsibility of the code *using* the class, to do appropriately (i.e, stack vs heap based allocation). – Ash Jun 04 '15 at 08:30
  • @PhilCK +1 for concise list. – Ash Jun 04 '15 at 08:30
  • @Ash The life time of heap objects is upto the programmers needs, but _usually_ most heap life time is determined by a stack object going out of scope. ie `shared_ptr`, `unique_ptr`, `std::vector` –  Jun 04 '15 at 10:14

2 Answers2

2
int m_int; // primitive type. hardly ever see a pointer

If I saw int *m my first reaction would be that it is an array of ints.

// For class instances, you always* seem to see this
 SomeOtherClass* m_some_other_class_instance_1;
 // and not this
 SomeOtherClass m_some_other_class_instance_2;

You might want to heap allocate your object if you need to delay its loading, and not have it constructed when the outer class is. Another reason you might do it is for polymorphic reasons. If SomeOtherClass is base class in your constructor you might initialise a different child class. if(some_condition) m_ptr = new Child1(); else m_ptr = new Child2(); Again you might want to wrap this in a unique_ptr so the destruction is automatic and you don't leak.

 // But lately, I've noticed that for std:: templates, it doesn't seem to be this
 vector<double>* m_vector_instance_1;
 // but rather this
 vector<double> m_vector_instance_2;

If you are holding on to a pointer of vector that isn't owned by this class a ptr isn't unexpected.

Heap allocating a vector (or other stl containers) doesn't make sense, partly because you are using them to take the pain out of dealing with c-style arrays, and managing the memory. Underneath a vector it will be heap allocated.

  SomeClass* some_class_instance_1 = new SomeClass();
  // SomeClass instance on heap
  // So all its members (both <xx>_1 and <xx>_2) are on heap as well
  // Hence all its members will stay alive beyond the scope of this function (or do they?)

Yes, all its stack members will stay alive until its deleted. Any heap allocated ones must be destroyed as well, if you are doing manual allocation the be sure to call the delete, but best to wrap around something like a unique_ptr or shared_ptr1

  SomeClass some_class_instance_2;
  // SomeClass instance on stack
  // So the only piece of data relating to SomeClass that's on the heap is what's pointed to by <xx>_1 members
  // But everything else will still stay alive within the scope of this function

This object and it members will get destroyed when it goes out of scope. Not though some of its members are pointers. Should they be pointing to a heap allocated member that has no other pointer you have a memory leak.

  // In conclusion, using either case above, members of a SomeClass instance stay alive for their intended period
  // So are <xx>_1 members overkill?

I can't think of a valid reason to heap allocate an stl container in the context above. Heap allocating other members might be required, but prefer not to when you can, and even then prefer using smart_ptrs when you can.

  // Ah, ha, ha, ha, stayin' alive, stayin' alive ...

This is C++, you will die a slow and painful death.

  • Finally, someone who actually *read* the intentions behind my post. Thank you. Preferred answer...until a better one comes along ;) – Ash Jun 04 '15 at 06:05
  • 1
    I've edited my question to provide some context, so please edit yours accordingly. +1 for the slow and painful death comment. – Ash Jun 04 '15 at 06:26
0

Your assumptions below are actually wrong

class SomeClass {
 int m_int; // primitive type. hardly ever see a pointer

No It depend on the context or situation something you havent seen doesn't mean people not used it.

 // For class instances, you always* seem to see this
 SomeOtherClass* m_some_other_class_instance_1;
 // and not this
 SomeOtherClass m_some_other_class_instance_2;

same here it again depend on your requirements

 // But lately, I've noticed that for std:: templates, it doesn't seem to be this
 vector<double>* m_vector_instance_1;
 // but rather this
 vector<double> m_vector_instance_2;
};

Scope & lifetime is different term and its not depend whether you use pointers or not.

see these questions for more details

Benefits of pointers?

https://softwareengineering.stackexchange.com/questions/16211/what-are-use-cases-and-advantages-of-pointers

Community
  • 1
  • 1
Ali786
  • 4,211
  • 6
  • 34
  • 54
  • Precisely why I used the terms 'hardly' and 'seem' in my comments. I know I haven't seen every single piece of code out there...simply noting what 'seems' to be common. So, time efficiency in passing members around between functions....is that the only reason why you'd need members that are pointers to data on the heap? – Ash Jun 04 '15 at 05:48
  • PS: Lifetime and scope can very much be related in some instances. Think 'local non-static' variables....as demonstrated by my example. – Ash Jun 04 '15 at 05:53