Почему структуры и класс существуют в С++?

Как известно, struct и class взаимозаменяемы во многих местах языка. Смутно, сами ключевые слова не обязательно соответствуют языку, используемому в стандарте. Например, в проекте стандарта N4567 [класс]/10,

Структура POD 109 - это неединичный класс, который является одновременно тривиальный класс и класс стандартного макета и не имеет нестатических данных члены типа non-POD struct, не-POD-соединение (или массив таких типов). Аналогичным образом, союз POD представляет собой объединение, которое является тривиальным класс и класс стандартного макета, и не имеет нестатических элементов данных типа не-POD-структуры, не-POD-соединение (или массив таких типов). A POD class - это класс, который является либо структурой POD, либо объединением POD.

В более упрощенных терминах struct и class взаимозаменяемы в следующих случаях:

  • объявление класса
  • объявление типа перечисленной области
  • специфицированный спецификатор типа, если только "класс" был объявлен с помощью union

Однако struct явно не может использоваться в объявлении шаблона для введения параметров шаблона типа:

template <struct T> // error

Я не вижу существенной разницы между struct и class, даже в примере POD выше, потому что структура POD, определенная в стандарте, может быть объявлена ​​с помощью struct или class.

[класс]/8 Структура стандартного макета - класс стандартного макета определяемый структурой класса или классом класса. Стандартное макетное соединение - это класс стандартного макета, определенный с помощью объединения классов классов.

Это кажется излишним и запутанным, вводя вопиющую несогласованность.

У меня есть два вопроса:

  • Существуют ли какие-либо технические отличия, которые я пропустил, что значительно отличает struct и class?

  • Каково обоснование, если таковое имеется, за этой неуклюжесть?

Я игнорирую разницу между спецификаторами доступа по умолчанию, потому что все это уже знают.

Ответы

Ответ 1

Почему в С++ существуют как struct, так и класс?

Причиной существования struct является совместимость с C.

Почему же тогда "C с классами" вводит новое ключевое слово class, когда вы можете использовать struct для одного и того же, вы можете спросить. См. Этот SO ответ для правдоподобных спекуляций. Короче говоря, это, вероятно, потому, что было желание сделать акцент на OOP, в котором class является широко используемым термином. Только Страуструп может знать наверняка.

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

Что нужно понимать, так это то, что понятие класса не одно и то же с ключевым словом class.

Существует три ключевых слова для объявления классов. Эти ключевые слова, известные как класс-ключи, это class, struct и union. Неединичные классы, объявленные с помощью class или struct, являются точно такими же, кроме . Классы Union отличаются от неединичных классов.

Однако структура явно не может использоваться в объявлении шаблона для введения параметров шаблона типа

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

Причина, по которой ключевое слово class было повторно использовано в контексте аргументов типа шаблона, вероятно, было связано с тем, что классы являются типами и поэтому обычно используются как параметры типа. Существует также ключевое слово typename, которое было добавлено позже и (почти) взаимозаменяемо с class в объявлении аргумента типа шаблона, но также используется в другом месте (зависимые имена типов), где class не используется. См. Этот ответ для ссылки и резюме о том, почему в этот контекст добавлено отдельное ключевое слово.

Почему struct не используется в контексте как эквивалент, вы можете спросить. Ну, это еще один вопрос к Страуструпу или комитету. Это был противоположный выбор, чем то, что сделал комитет, когда был введен enum class/enum struct.

Я не вижу существенной разницы между struct и class

Хорошо. Нет никаких исключений, кроме

Это кажется излишним и запутанным, вводя вопиющую несогласованность.

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

  • Существуют ли какие-либо технические отличия, которые я пропустил, которые значительно различают структуру и класс?

Я уже ответил, но, чтобы быть понятным, существует разница нет между классами, объявленными с ключевыми словами struct и class, кроме .

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

Ответ 2

Почему в С++ существуют как struct, так и класс?

struct исходит из C и существует на С++ главным образом по соображениям совместимости с языком программирования C.

Есть ли технические отличия, которые я пропустил значительно различают struct и class?

Основное различие между struct и a class заключается в том, что для struct его члены имеют public доступ по умолчанию, тогда как для class его члены имеют private доступ по умолчанию.

Ключевое слово class, используемое в аргументах шаблона, не определяет класс, а скорее аргумент шаблона non type и может использоваться взаимозаменяемо с ключевым словом typename.

Что касается того, почему вы не можете использовать ключевое слово struct для указания аргумента типа non type, причины являются историческими, и я думаю, вы должны спросить Bjarne для него:) или ссылаться на это SO answer для информации за кулисами.