Точка с запятой после фигурных скобок объявления класса

82

Почему в классах C ++ стоит точка с запятой после закрывающей фигурной скобки? Я регулярно забываю об этом и получаю ошибки компилятора, а значит, теряю время. Мне это кажется несколько лишним, что вряд ли так. Действительно ли люди делают такие вещи, как:

class MyClass
{
.
.
.
} MyInstance;

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

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

SmacL
источник
4
Это может помочь: cpptalk.net/…
Майкл Харен,
@Michael, спасибо за ссылку. С исторической точки зрения это имеет смысл, и если C ++ допускает все грамматики C, а классы C ++ являются синонимами структур, у нас остается необходимая точка с запятой в конце класса.
SmacL
3
@ Брайан, да серьезный вопрос. Я прекрасно понимаю, что должен смириться с этим, но мне любопытно, что лежит в основе дизайна и реализации.
SmacL,
Хорошо, но, возможно, вам следует отредактировать свой вопрос, включив в него необходимое обоснование дизайна. Как бы то ни было, он побуждает людей задавать такие вопросы, как «почему фигурная скобка»? :) Возможно, вам будет интересно прочитать книгу Страуструпа «Дизайн и эволюция C ++», хотя она охватывает более важные вопросы, чем точки с запятой в конце классов.
Брайан Нил,
@ Брайан, честно, и это было на грани того, стоит ли делать это вики. Вопрос был задан после исключения точки с запятой в регулярно используемом заголовке в большой сборке. Это стоило мне получаса, отсюда и визит в SO. Вопрос отредактирован согласно вашему предложению.
SmacL,

Ответы:

47

Точка с запятой после закрывающей фигурной скобки в объявлении типа требуется языком. Так было с самых ранних версий C.

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

void Example() {
  struct { int x; } s1;
  s1.x = 42;

  struct ADifferentType { int x; };
}

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

ДжаредПар
источник
Почему я не могу просто создать тип с областью действия без указания MyInstance? Кажется странным, когда вы объединяете два действия: объявление нового типа и объявление новой переменной.
Николай Голубев
@Mykola, ты можешь и то, и другое. См. Добавленный
мной
71

Ссылка предоставлена @MichaelHaren , как представляется , обеспечивают основную причину . Точка с запятой (как указывали другие) унаследована от C. Но это не объясняет, почему C использовал ее в первую очередь. Обсуждение включает эту жемчужину примера:

struct fred { int x; long y; }; 
main() 
{ 
  return 0; 
} 

Более старые версии C имели неявный тип возвращаемого значения int из функции, если не указано иное. Если мы опустим символ ;в конце определения структуры, мы не только определяем новый тип fred, но и объявляем, что main()он вернет экземпляр fred. Т.е. код будет разбираться так:

struct fred { int x; long y; } main()
{ 
  return 0; /* invalid return type, expected fred type */
} 
Натан
источник
1
Да, неявный возвращаемый тип int мог бы уничтожить все здесь. Хорошая жемчужина
Gaspa79
17

Я думаю, это потому, что классы являются объявлениями, даже когда им нужны фигурные скобки для группировки. И да, есть исторический аргумент, что, поскольку в C вы могли сделать

struct
{
  float x;
  float y;
} point;

в C ++ вы должны иметь возможность делать то же самое, для classобъявления имеет смысл вести себя таким же образом.

размотать
источник
11

Это сокращение от

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

Точка с запятой после фигурных скобок в объявлении класса на самом деле лишняя, но именно так определяется C ++. Точка с запятой после объявления переменной всегда нужна и имеет смысл.

Стефан Штайнеггер
источник
1
Итак, требует ли C ++ точка с запятой после каждого объявления?
Лоай Нагати
1
Обратите внимание, что таким образом вы не можете создать объект анонимного класса, а можете наоборот.
Кевин
5

Я не использую такие объявления

class MyClass
{
.
.
.
} MyInstance;

Но в этом случае я могу понять, почему там точка с запятой.
Потому что это как int a;- объявление переменной.

Вероятно, для согласованности, поскольку вы можете опустить точку с запятой MyInstance.

Николай Голубев
источник
3

Он нужен после a structпо соображениям совместимости, и как бы вы этого хотели:

struct MyStruct { ... };
class  MyClass  { ... }    //inconsistency
Зифре
источник
1
А что насчет namespace myNamespace { ... } // inconsistent but valid?
Chris K
3

В C / C ++ оператор; является терминатором утверждения. Все утверждения заканчиваются; чтобы избежать двусмысленности (и упростить синтаксический анализ). В этом отношении грамматика последовательна. Даже несмотря на то, что объявление класса (или любой блок в этом отношении) состоит из нескольких строк и разделен символом {}, он все еще является просто оператором ({} является частью оператора), следовательно, его необходимо завершить; (; Не является разделителем / разделителем)

В вашем примере

class MyClass{...} MyInstance;

это полное заявление. Можно определить несколько экземпляров объявленного класса в одном операторе

class MyClass{...} MyInstance1, MyInstance2;

Это полностью соответствует объявлению нескольких экземпляров примитивного типа в одном операторе:

int a, b, c;

Причина, по которой нечасто можно увидеть такое описание класса и экземпляра, заключается в том, что экземпляр мог? Only? быть глобальной переменной, и вам не очень часто нужны глобальные объекты, если они не являются статическими и / или простыми структурами старых данных.

Роджер Нельсон
источник
2
Но определение функции - это тоже утверждение, но без точек с запятой.
Jiapeng Zhang 02