Будут ли выделенные в куче объекты иметь своих членов в стеке?

Давайте рассмотрим этот пример.

class StaticlyManagedObject
{
   //some class members....
}
class DynamiclyManagedObject
{
   StaticlyManagedObject _staticlyManagedObject; //is this still allocated at the stack?

}

class Foo
{
  DynamiclyManagedObject * _dynamiclyManagedObject; //will be allocated in the heap.
  Foo()
  {
      _dynamiclyManagedObject = new DynamiclyManagedObject();
  }
}

Мне сказали, что когда мы не используем динамическое управление памятью в C++, все размещается в стеке, и нам не нужно управление памятью.

Однако в этом примере. у нас есть динамически размещенный объект, который называется DynamiclyManagedObject. Я создаю его экземпляр в конструкторе Foo. Мой вопрос: что происходит со статически управляемым членом данных DynamiclyManagedObject?

Он все еще создается в стеке или.. из-за того, что DynamiclyManagedObject создан в куче, каждый его элемент данных попадает в кучу.

4 ответа

Решение

Субобъект имеет ту же продолжительность хранения, что и весь объект, частью которого он является. Если экземпляр DynamiclyManagedObject динамически распределяется, то StaticlyManagedObject член будет уничтожен, когда DynamiclyManagedObject уничтожен

Неформально можно сказать, что подобъект будет в куче, если и только если весь объект находится в куче. Тем не менее, продолжительность хранения является технически правильным способом говорить об этом; куча и стек являются деталями реализации.

StaticlyManagedObject это неправильно. Распределяется динамически, так же, как родительский объект.

Вложенные члены класса используют тот же метод выделения, что и родительский объект, если они специально не отмечены staticв этом случае они не выделяются во время создания объекта или они специально выделяются динамически в конструкторах.

Является ли член вашего класса другим классом или элементарным типом данных:

class DynamiclyManagedObject
{
   StaticlyManagedObject _staticlyManagedObject;
   int some_integer;
};

Не имеет значения, является ли член класса другим классом или элементарным типом данных, таким как int, И "_staticlyManagedObject", и "some_integer" полностью идентичны друг другу, за исключением их типа (конечно, это не совсем тривиальный атрибут). Один intдругой - какой-то другой класс. Тип члена класса не влияет на его область действия. Либо весь класс выделяется динамически, либо нет. Или он расположен в автоматической области (как вы говорите, в стеке).

Единственным исключением из этого правила является static член класса:

class DynamiclyManagedObject
{
   StaticlyManagedObject _staticlyManagedObject;
   int some_integer;

   static std::string some_string;
};

Правила разные для some_string, Обратите внимание, что это настоящий статический член класса, а не член класса, тип которого StaticallyManagedObject,

Независимо от типа (будь то структура, класс или примитив), при использовании оператора new в C++ или динамического выделения в C с помощью malloc (который получает размер вашей структуры в качестве параметра, чтобы узнать, сколько байтов выделить) - все требуемого пространства (содержащего элементы) будет помещено в кучу.

Эти вызовы возвращают указатель на зону памяти кучи, которая была выделена.

Переменные и параметры локальной функции всегда помещаются в стек.

Если вы объявите локальную переменную указателя, ее место будет по-прежнему в стеке, но вам придется использовать методы динамического выделения, упомянутые выше, чтобы выделить память кучи, на которую фактически будет указывать выделенный стеком указатель.

Другие вопросы по тегам