Каковы различия между & ldquo; универсальным & rdquo; типы в C ++ и Java?

У Java есть дженерики, а C ++ предоставляет очень сильную модель программирования с template с. Итак, в чём же разница между дженериками C ++ и Java?

148
задан 19.05.2020, 00:16

9 ответов

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

template <typename T> T sum(T a, T b) { return a + b; }

метод выше добавляет два объекта того же типа и может использоваться для любого типа T, который имеет "+" доступный оператор.

В Java необходимо определить тип, если Вы хотите звонить, методы на объектах передали, что-то как:

<T extends Something> T sum(T a, T b) { return a.add ( b ); }

В C++ универсальные функции/классы могут только быть определены в заголовках, так как компилятор генерирует различные функции для различных типов (что это вызывается с). Таким образом, компиляция медленнее. В Java компиляция не имеет крупного штрафа, но Java использует технику, названную "стиранием", где универсальный тип стирается во времени выполнения, таким образом, в Java во время выполнения на самом деле звонит...

Something sum(Something a, Something b) { return a.add ( b ); }

, Таким образом, универсальное программирование в Java не действительно полезно, это - только немного синтаксического сахара для помощи с новой конструкцией foreach.

РЕДАКТИРОВАНИЕ: мнение выше о полноценности было записано младшим сам. Дженерики Java помогают с безопасностью типов, конечно.

132
ответ дан 19.05.2020, 00:19
  • 1
    Да, довольно хороший ответ до того последнего предложения. – Laurence Gonsalves 19.05.2020, 00:20
  • 2
    Я думаю , синтаксический сахар полезен. – poitroae 19.05.2020, 00:20
  • 3
    Он совершенно корректен, что это - просто тщательно продуманный синтаксический сахар. – alphazero 19.05.2020, 00:21
  • 4
    Вы упустили важную суть различия, что можно использовать для инстанцирования дженерика. В C++ возможно использовать шаблон < международный N> и доберитесь, различный результат для любого числа раньше инстанцировал его. Это используется в течение времени компиляции meta проигры. Как ответ в: stackoverflow.com/questions/189172/c-templates-turing-complete – stonemetal 19.05.2020, 00:21
  • 5
    It' s не чисто синтаксический сахар. Компилятор использует эту информацию для проверки типов. Даже при том, что информация isn' t доступный во времени выполнения I wouldn' t называют что-то скомпилированным использованием просто " синтаксический sugar". при вызове его, что, хорошо тогда C является просто синтаксическим сахаром для блока и that' s просто синтаксический сахар для машинного кода:) – dtech 19.05.2020, 00:22

Дженерики Java в широком масштабе отличающиеся от шаблонов C++.

В основном в шаблонах C++ в основном прославленный набор препроцессора/макроса ( Примечание: , так как некоторые люди кажутся не могущими постигать аналогию, я не говорю, что шаблонная обработка является макросом). В Java они - в основном синтаксический сахар для уменьшения шаблонного кастинга Объектов. Вот довольно достойное введение в шаблоны C++ по сравнению с дженериками Java .

Для разработки по этому вопросу: при использовании шаблона C++ Вы в основном создаете другую копию кода, так же, как если бы Вы использовали #define макрос. Это позволяет Вам делать, вещам нравится, имеют int параметры в шаблонных определениях, которые определяют размеры массивов и такого.

Java не работает как этот. В Java вся степень объектов от [1 111] java.lang. Объект так, предварительные дженерики, Вы написали бы код как это:

public class PhoneNumbers {
  private Map phoneNumbers = new HashMap();

  public String getPhoneNumber(String name) {
    return (String)phoneNumbers.get(name);
  }

  ...
}

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

public class PhoneNumbers {
  private Map<String, String> phoneNumbers = new HashMap<String, String>();

  public String getPhoneNumber(String name) {
    return phoneNumbers.get(name);
  }

  ...
}

И это - все Дженерики Java: обертки для кастинга объектов. Поэтому Дженерики Java не усовершенствованы. Они используют стирание типа. Это решение было принято, потому что Дженерики Java пришли настолько поздно в части, что они не хотели повреждаться, обратная совместимость (Map<String, String> применимо каждый раз, когда Map требуется). Сравните это с.Net/C#, где стирание типа не используется, который приводит ко всем видам различий (например, можно использовать типы примитивов и IEnumerable и IEnumerable<T> перенос никакое отношение друг к другу).

И класс с помощью дженериков, скомпилированных с Java 5 +, компилятор применим на JDK 1.4 (предполагающий, что он не использует никакие другие функции или классы, которые требуют Java 5 +).

Вот почему Дженерики Java называют синтаксический сахар .

, Но это решение о том, как сделать, дженерики имеют сильные воздействия так так, чтобы (превосходный) дженерики FAQ Java возникли для ответа на многих, многие люди вопросов имеют о Дженериках Java.

шаблоны C++ имеют много функций, которые не делают Дженерики Java:

, Например:

public class ObservableList<T extends List> {
  ...
}

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

Кроме различий с дженериками, для полноты, вот основное сравнение C++ и Java другой ).

И я могу также предложить Взгляды в Java. Как программист на C++ много понятий как объекты уже будет второй натурой, но существуют тонкие различия, таким образом, может стоить иметь вводный текст, даже если Вы просматриваете части.

Многое из того, что Вы изучите при изучении Java, является всеми библиотеками (и стандарт - что прибывает в JDK - и нестандартный, который включает наиболее часто используемые вещи как Spring). Синтаксис Java является более подробным, чем синтаксис C++ и не имеет большого количества функций C++ (например, перегрузка оператора, множественное наследование, механизм деструктора, и т.д.), но это строго не делает это подмножеством C++ также.

119
ответ дан 19.05.2020, 00:17
  • 1
    Важный, чтобы отметить, что проблема стирания типа означает больше, чем просто назад совместимость для Map map = new HashMap<String, String>. Это означает, что можно развернуть новый код старой JVM, и это будет работать из-за общих черт в байт-коде. – Yuval Adam 19.05.2020, 00:17
  • 2
    Нет, they' ре, не эквивалентное в понятии. Существует некоторое перекрытие в понятии, но не очень. Оба позволяют Вам создавать List< T> но that' s о том, насколько это идет. Шаблоны C++ идут намного далее. – jalf 19.05.2020, 00:18
  • 3
    Шаблон кода очень отличающийся, чем копия-и-вставка. Если Вы думаете с точки зрения макрорасширения, рано или поздно you' ll быть пораженным тонкими ошибками, такими как этот: womble.decadentplace.org.uk/c ++/… – Nemanja Trifunovic 19.05.2020, 00:18
  • 4
    You' ll отмечают, что я сказал " в основном прославленный preprocessor/macro". это была аналогия, потому что каждое объявление шаблона создаст больше кода (в противоположность Java/C#). – cletus 19.05.2020, 00:18
  • 5
    Они не эквивалентны в понятии. Лучший пример, являющийся любопытно повторяющимся шаблонным шаблоном. Второсортное, ориентируемое на политику на дизайн. Третье лучше всего быть тем, что C++ позволяет целым числам быть переданными в угловых скобках (myArray< 5>). – Max Lybbert 19.05.2020, 00:19

@Keith:

, Что код является на самом деле неправильным и кроме меньших незначительных сбоев (template опущенный, синтаксис специализации смотрит по-другому), частичная специализация не делает работа над шаблонами функций, только над шаблонами классов. Код однако работал бы без частичной шаблонной специализации, вместо этого с помощью простой перегрузки:

template <typename T> T sum(T a, T b) { return a + b; }
template <typename T> T sum(T* a, T* b) { return (*a) + (*b); }
1
ответ дан 19.05.2020, 00:17
  • 1
    О, самодовольный тип, ya? Очень хороший! +1:) – Yardboy 22.11.2019, 20:59
  • 2
    Почему это - ответ и не комментарий? – Laurence Gonsalves 19.05.2020, 00:18
  • 3
    @Laurence: на этот раз, потому что это было отправлено задолго до того, как комментарии были реализованы на Переполнении стека. Для другого, потому что it’s не только комментарий †“it’s также ответ на вопрос: что-то как вышеупомянутый код isn’t возможный в Java. – Konrad Rudolph 19.05.2020, 00:18

Другим преимуществом шаблонов C++ является специализация.

template <typename T> T sum(T a, T b) { return a + b; }
template <typename T> T sum(T* a, T* b) { return (*a) + (*b); }
Special sum(const Special& a, const Special& b) { return a.plus(b); }

Теперь при вызове суммы с указателями второй метод назовут при вызове суммы с неуказательными объектами, первый метод назовут, и если Вы будете звонить sum с Special объекты, третье назовут. Я не думаю, что это возможно с Java.

3
ответ дан 19.05.2020, 00:18

Java (и C#) дженерики, кажется, простой механизм замены типа выполнения.
шаблоны C++ являются конструкцией времени компиляции, которые дают Вам способ изменить язык для удовлетворения потребностям. Они - на самом деле просто функциональный язык, который компилятор выполняет во время компиляции.

3
ответ дан 19.05.2020, 00:18

Существует большое объяснение этой темы в Дженерики Java и Наборы Maurice Naftalin, Philip Wadler. Я настоятельно рекомендую эту книгу. Заключить в кавычки:

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

считайте полное объяснение здесь .

alt text
(источник: oreilly.com )

13
ответ дан 19.05.2020, 00:20

Другая функция, что шаблоны C++ имеют тот Java дженерики, не делает специализация. Это позволяет Вам иметь другую реализацию для определенных типов. Таким образом, у Вас может, например, быть высоко оптимизированная версия для интервал , все еще имея универсальную версию для остальной части типов. Или у Вас могут быть различные версии для указателя и неуказательных типов. Это пригождается, если Вы хотите воздействовать на разыменованный объект при вручении указателя.

15
ответ дан 19.05.2020, 00:21
  • 1
    +1 шаблонная специализация невероятно важна для метапрограммирования времени компиляции - это различие сам по себе делает дженерики Java что намного менее мощными – Faisal Vali 19.05.2020, 00:21

C++ имеет шаблоны. Java имеет дженерики, которые выглядят вид вида подобных шаблонов C++, но они очень, очень отличающиеся.

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

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

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

 

78
ответ дан 19.05.2020, 00:22
  • 1
    Это - довольно хорошее, краткое объяснение. Одна тонкая настройка I' d испытать желание сделать то, что дженерики Java являются инструментом для того, чтобы автоматически генерировать преобразования типа , которые, как гарантируют, будут безопасны (с некоторыми условиями). До некоторой степени they' ре, связанное с C ++' s const. Объект в C++ won' t быть измененным через const указатель, если const - мыс не является литым далеко. Аналогично, неявные броски, созданные универсальными типами в Java, как гарантируют, будут " safe" если параметры типа не являются вручную литыми далеко где-нибудь в коде. – Laurence Gonsalves 19.05.2020, 00:22

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

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

, Если Вы знакомы с шаблонным механизмом C++, Вы могли бы думать, что дженерики подобны, но подобие является поверхностным. Дженерики не генерируют новый класс для каждой специализации, и при этом они не разрешают “template метапрограммирование. ”

от: Дженерики Java

5
ответ дан 19.05.2020, 00:22

Теги

Похожие вопросы