2016-08-19 2 views
1

Рассмотрим этот пример.Будут ли выделенные объекты кучи выделены в стеке?

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 I, который создает этот объект внутри конструктора Foo. Мой вопрос заключается в том, что происходит со статически управляемым элементом данных объекта DynamiclyManagedObject?

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

ответ

4

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

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

+0

Большое спасибо за хорошее объяснение. Все ответы, которые я получил ниже, одинаково велики. Дополнительная благодарность за упоминание продолжительности хранения. Быстрый поиск показал так много ответов. Теперь я могу найти в нем больше. – Nusakan

3

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

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

+0

Благодарим вас за разъяснение, что «StaticlyManagedObject» выделяется динамически. – Nusakan

2

ли член вашего класса еще один класс, или элементарный тип данных:

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.

0

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

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

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

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

Смежные вопросы