Semi Colon после привязки декларации класса

Извините заранее, что, вероятно, является глупым вопросом, но в классах С++, почему точка с запятой после закрывающей фигурной скобки? Я регулярно забываю об этом, получаю ошибки компилятора и, следовательно, теряю время. Кажется мне несколько лишним, что вряд ли будет иметь место. Люди действительно делают что-то вроде

class MyClass
{
.
.
.
} MyInstance;

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

Ответ 1

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

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

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

  struct ADifferentType { int x; };
}

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

Ответ 2

Ссылка, предоставленная @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 */
} 

Ответ 3

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

struct
{
  float x;
  float y;
} point;

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

Ответ 4

Это сокращение для

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

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

Ответ 5

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

class MyClass
{
.
.
.
} MyInstance;

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

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

Ответ 6

Это необходимо после struct для соображений совместимости и как вам это понравится:

struct MyStruct { ... };
class  MyClass  { ... }    //inconsistency

Ответ 7

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

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

class MyClass{...} MyInstance;

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

class MyClass{...} MyInstance1, MyInstance2;

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

int a, b, c;

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