2016-12-02 2 views
1

Скажите Pokemon это класс. Рассмотрим этот фрагмент:Что происходит с «потерянными» объектами стека?

Pokemon Eve(4,3); //call to constructor, creating first object on the stack 
Eve=Pokemon(3,5); //call to constructor again, creating a second object on the stack 

Оба объекта создаются в стеке. После выполнения второй строки первый объект (с параметрами 4,3) больше не может быть доступен. Что с ним происходит? Что такое жаргон, используемый для описания этого процесса? Вывоз мусора?

ответ

6

Я думаю, вы неправильно поняли, что происходит. Объект, созданный как Eve, не «потерян» после второй строки. Фактически, это все тот же объект впоследствии (под которым я имею в виду, что он все еще имеет тот же адрес памяти). Вторая строка присваивает другое значение объекту, вызывая оператор присваивания на объекте Eve. Параметр, переданный оператору присваивания, является временным объектом, созданным Pokemon(3,5).

Это временный объект - Pokemon(3,5), который разрушается после второй линии. Его уничтожение - это не «сбор мусора» или даже освобождение кучи, поскольку оно является объектом стека в первую очередь и, следовательно, не требует такого.

Я думаю, вы думаете об этом с точки зрения Java/C# или подобных управляемых языков, которые имеют только ссылки на объекты, а не прямые объекты. В C++ с приведенным выше кодом вы имеете дело с объектами напрямую. Для того, чтобы увидеть что-то эквивалентное тому, что вы имеете в виду, подумайте:

Pokemon* Eve = new Pokemon(4,3); 
Eve=new Pokemon(3,5); 

Здесь мы используем указатели и кучу, а не стек. В этом случае вторая строка действительно «теряет» исходный объект, потому что это указатель, который переназначен. Это вид, аналогичный тому, что происходит в Java/C# с нормальным назначением. Разумеется, разница заключается в том, что у C++ нет сборщика мусора, поэтому в приведенном выше первоначальном объекте действительно теряется в смысле утечки памяти.

1

Объекты не создаются в куче, а непосредственно в стеке, поэтому пространство не теряется (т. Е. Нет выделенного пространства, которое становится недоступным) - назначение просто повторно использует память, выделенную инициализацией Eve.

Отредактировано: Более подробная формулировка вокруг «переписывания» раздора.

+0

Я бы не сказал, что выделенное пространство «просто перезаписано». Оператор присваивания C++ может выполнять несколько действий перед перезаписью чего-либо. Он не может ничего перезаписывать в зависимости от реализации 'operator =()'! –

+0

Это именно то, что происходит с реализацией по умолчанию, и, возможно, это то, что должно делать любое нормальное переопределение, насколько это касается семантики присваивания. Разумеется, этот вопрос дает прекрасную возможность подключиться к подробному описанию специальных операторов на C++, но я очень сомневаюсь, что OP это вызвал. – shinobi

+1

Совершенно верно, поэтому я не спустил вниз. Однако все зависит от того, что происходит в классе «Покемон».Наиболее очевидной причиной переопределения 'operator =()' является глубокая копия указателей, которая не просто «просто перезаписывает» содержимое класса. Мой комментарий был более справедливым, чтобы указать на то, что мы не можем делать предположения о классе OP 'Pokemon' и делать заявления сложения. –

3

Это называется «оператор присваивания», или «=».

Второй объект - это временный объект, а не первый. После его создания вызывается оператор присваивания первого объекта, чтобы присвоить значение второго объекта первому объекту.

После этого вызывается деструктор второго объекта, а второй объект уничтожается. Куда он идет? К большому ведерке в небе. Он исчез.

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