Подтвердить что ты не робот

В чем основное отличие создания объектов между Java и С++?

Я готовлюсь к экзамену на Java, и один из вопросов, который был на предыдущем экзамене, был: "В чем основное отличие в создании объектов между Java и С++?"

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

Любые идеи?

4b9b3361

Ответ 1

В дополнение к другим отличным ответам, одна вещь очень важна и обычно игнорируется/забывается или неправильно понята (что объясняет, почему я подробно описываю процесс ниже):

  • В Java методы являются виртуальными даже при вызове из конструктора (что может привести к ошибкам) ​​
  • В С++ виртуальные методы не являются виртуальными при вызове из конструктора (что может привести к недоразумениям)

Что?

  • Представьте себе базовый класс с виртуальным методом foo().
  • Представьте себе производный класс, наследующий от Base, который переопределяет метод foo()

Разница между С++ и Java:

  • В Java вызов foo() из конструктора базового класса вызовет Derived.foo()
  • В С++ вызов foo() из конструктора базового класса вызовет Base.foo()

Почему?

"Ошибки" для каждого языка разные:

  • В Java вызов любого метода в конструкторе может привести к тонким ошибкам, поскольку переопределенный виртуальный метод может попытаться получить доступ к переменной, которая была объявлена ​​/инициализирована в классе Derived.

Концептуально задача конструкторов состоит в том, чтобы привести объект в существование (что вряд ли является обычным подвигом). Внутри любого конструктора весь объект может быть только частично сформирован - вы можете знать только, что объекты базового класса были инициализированы, но вы не можете знать, какие классы унаследованы от вас. Однако вызов метода с динамической привязкой достигает "вперед" или "наружу" в иерархию наследования. Он вызывает метод в производном классе. Если вы сделаете это внутри конструктора, вы вызываете метод, который может манипулировать членами, которые еще не были инициализированы, - верный рецепт катастрофы.

Брюс Экель, http://www.codeguru.com/java/tij/tij0082.shtml

  • В С++ нужно помнить, что виртуальная работа не будет работать так, как ожидалось, поскольку будет вызван только метод текущего построенного класса. Причина заключается в том, чтобы избежать доступа к членам данных или даже к тем методам, которые еще не существуют.

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

Скотт Мейерс, http://www.artima.com/cppsource/nevercall.html

Ответ 2

В чем основное отличие создания объектов между Java и С++?

В отличие от Java, в С++ объекты также могут быть созданы в стеке.

Например, в С++ вы можете написать

Class obj; //object created on the stack

В Java вы можете написать

Class obj; //obj is just a reference(not an object)
obj = new Class();// obj refers to the object

Ответ 3

Помимо проблем с кучей/стека, я бы сказал: конструкторы С++ имеют списки инициализации, в то время как Java использует назначение. Подробнее см. http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6.

Ответ 4

Я бы ответил: С++ позволяет создавать объект повсюду: в куче, стеке, члене. Java заставляет выделять объекты в куче, всегда.

Ответ 5

В Java виртуальная машина Java (JVM), которая выполняет Java-код , должна может 1 регистрировать все создаваемые объекты (или ссылки на них, если быть точным), поэтому что выделенная для них память впоследствии может быть автоматически освобождена сборкой мусора, когда объекты больше не ссылаются.

РЕДАКТИРОВАТЬ: Я не уверен, может ли это быть связано с созданием объекта в строгом смысле, но это, безусловно, происходит между созданием и присваиванием переменной, даже без явного присвоения (когда вы создать объект без его назначения, JVM должен автоматически освободить его через некоторое время после этого, поскольку больше нет ссылок).

В С++ только объекты, созданные в стеке, автоматически освобождаются (когда они выходят из области видимости), если вы не используете какой-либо механизм, который обрабатывает это для вас.

1: В зависимости от реализации JVM.

Ответ 6

Существует одно основное различие между конструкторами в С++ и Java. Другие отличия следуют из этого проектного решения.

Основное отличие состоит в том, что JVM сначала инициализирует все члены до нуля, прежде чем приступать к выполнению любого конструктора. В С++ инициализация члена является частью конструктора.

В результате, при выполнении конструктора базового класса в С++ члены производного класса еще не инициализированы! В Java они инициализируются нулями.

Следовательно, правило, которое объясняется в paercebal answer, что виртуальные вызовы, вызываемые из конструктора, не могут спуститься в производного класса. В противном случае можно было бы получить доступ к неинициализированным элементам.

Ответ 7

Предполагая, что С++ использует alloc() при новом вызове, то это может быть то, что они находясь в поиске. (Я не знаю С++, поэтому я могу быть очень не прав)

Модель памяти Java выделяет кусок памяти, когда она им нужна, и для каждого нового, которое она использует это заранее выделенная область. Это означает, что новый в java просто устанавливает указатель на сегмент памяти и перемещение свободного указателя в то время как новый в С++ (если он использует malloc в фоновом режиме) приведет к системному вызову.

Это делает объекты более дешевыми для создания на Java, чем языки, использующие malloc; по крайней мере, когда нет инициализационного закрытия.

Короче - создание объектов на Java дешево - не беспокойтесь об этом, если вы не создаете множество из них.