堆栈成员与C ++对象中的堆成员

时间:2015-06-04 05:10:55

标签: c++ pointers object

我提前道歉,因为我没有按照具体的答案。只是一些见解将不胜感激。下面的评论(以及代码)概述了一些观察,澄清和不确定性。这里的问题实际上是成员的终身。

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 ...
}

就上下文而言,我们假设SomeClass不知道它周围的任何其他类,并且不希望现在传递任何内容...因此构造函数可能只是初始化其成员无论如何,编写它的人都不知道如何使用这个类。唯一关心的是会员还活着。

我已经阅读了这些帖子,但它们并不相关:

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++

2 个答案:

答案 0 :(得分:1)

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

如果我看到int *m我的第一反应就是它是一系列的整数。

// 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;

如果需要延迟加载,可能需要堆分配对象,而不是在外部类时构造它。您可能会这样做的另一个原因是出于多态性原因。如果SomeOtherClass是构造函数中的基类,则可以初始化另一个子类。 if(some_condition) m_ptr = new Child1(); else m_ptr = new Child2(); 您可能希望将其包装在unique_ptr中,以便销毁是自动的,并且您不会泄漏。

 // 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;

如果你持有一个不属于这个类的向量指针,那么ptr就不会出乎意料。

分配向量(或其他stl容器)的堆没有意义,部分原因是因为您正在使用它们来解决处理c样式数组和管理内存的痛苦。在矢量下面,它将被堆分配。

  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?)

是的,它的所有堆栈成员都会保留,直到删除它为止。任何堆分配的那些也必须被销毁,如果你正在进行手动分配,一定要调用删除,但最好包括像unique_ptrshared_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

此对象及其成员在超出范围时将被销毁。虽然它的一些成员是指针。如果它们指向没有其他指针的堆分配成员,则会发生内存泄漏。

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

我无法想到在上面的上下文中堆积分配stl容器的正当理由。可能需要分配其他成员的堆,但最好不要在可能的情况下,甚至更愿意尽可能使用smart_ptrs

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

这是C ++,你会死于缓慢而痛苦的死亡。

答案 1 :(得分:0)

您的假设实际上是错误的

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;
};

范围&amp;生命周期是不同的术语,它不取决于你是否使用指针。

有关详细信息,请参阅这些问题

Benefits of pointers?

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