В чем основное отличие создания объектов между Java и C ++? - PullRequest
19 голосов
/ 29 сентября 2010

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

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

Есть идеи?

Ответы [ 7 ]

25 голосов
/ 29 сентября 2010

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

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

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

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
19 голосов
/ 29 сентября 2010

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

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

Что?

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

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

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

Почему?

«Ошибки» для каждого языка различны:

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

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

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

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

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

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

8 голосов
/ 29 сентября 2010

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

4 голосов
/ 29 сентября 2010

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

2 голосов
/ 29 сентября 2010

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

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

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

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

1 голос
/ 29 сентября 2010

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

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

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

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

0 голосов
/ 29 сентября 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...