Будут ли выделенные в куче объекты иметь своих членов в стеке?
Давайте рассмотрим этот пример.
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 (который получает размер вашей структуры в качестве параметра, чтобы узнать, сколько байтов выделить) - все требуемого пространства (содержащего элементы) будет помещено в кучу.
Эти вызовы возвращают указатель на зону памяти кучи, которая была выделена.
Переменные и параметры локальной функции всегда помещаются в стек.
Если вы объявите локальную переменную указателя, ее место будет по-прежнему в стеке, но вам придется использовать методы динамического выделения, упомянутые выше, чтобы выделить память кучи, на которую фактически будет указывать выделенный стеком указатель.