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

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

class MyClass
{
.
.
.
} MyInstance;

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

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


person SmacL    schedule 24.04.2009    source источник
comment
@Michael, спасибо за ссылку. С исторической точки зрения это имеет смысл, и если C ++ допускает все грамматики C, а классы C ++ являются синонимами структур, у нас остается необходимая точка с запятой в конце класса.   -  person SmacL    schedule 24.04.2009
comment
@ Брайан, да серьезный вопрос. Я прекрасно понимаю, что должен жить с этим, но мне любопытно, что за дизайн и реализация лежат в основе.   -  person SmacL    schedule 24.04.2009
comment
Хорошо, но, возможно, вам следует отредактировать свой вопрос, включив в него необходимое обоснование дизайна. Как бы то ни было, он побуждает людей задавать вопросы, например, почему фигурная скобка? :) Возможно, вам будет интересно прочитать книгу Страуструпа «Дизайн и эволюция C ++», хотя она охватывает более важные вопросы, чем точки с запятой в конце классов.   -  person Brian Neal    schedule 24.04.2009
comment
@ Брайан, достаточно честно, и это было пограничным вопросом, стоит ли использовать его вики. Вопрос был задан после исключения точки с запятой в регулярно используемом заголовке в большой сборке. Это обошлось мне в полчаса, отсюда и визит в SO. Вопрос отредактирован в соответствии с вашим предложением.   -  person SmacL    schedule 24.04.2009
comment
Классы по сути являются структурами, единственная разница - их уровень доступа по умолчанию (частный или общедоступный). Так что разницы в точках с запятой нет. Думаю, именно поэтому я был так недоверчив. :)   -  person Brian Neal    schedule 24.04.2009
comment
Я рекомендую писать каждый класс, предварительно написав скелет: class ClassName {\ n private: \ n public: \ n}; а затем заполните детали. Или, как вы сказали, с помощью IDE, которая сделает это за вас   -  person MatrixFrog    schedule 25.04.2009
comment
@BrianNeal, этот вопрос довольно старый на данный момент, но я бы сказал, что классы имеют фундаментальное отличие от структур в том, что они также могут содержать функции. Я имею в виду, что да, они действительно похожи на структуры, но уровень доступа по умолчанию - не единственное различие, и возможность инкапсулировать функции делает их довольно разными. Все это только для того, чтобы сказать, что я считаю, что замечать некоторую разницу между ними вполне оправданно.   -  person Ryan Blanchard    schedule 26.02.2021
comment
Структуры @RyanBlanchard могут иметь функции-члены в C ++.   -  person Brian Neal    schedule 26.02.2021


Ответы (7)


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

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

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

  struct ADifferentType { int x; };
}

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

person JaredPar    schedule 24.04.2009
comment
Почему я не могу просто создать тип с областью действия без указания MyInstance? Кажется странным, когда вы объединяете два действия: объявление нового типа и объявление новой переменной. - person Mykola Golubyev; 24.04.2009
comment
@Mykola, ты можешь и то, и другое. См. Добавленный мной образец - person JaredPar; 24.04.2009

ссылка, предоставленная @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 */
} 
person Nathan    schedule 22.05.2014
comment
Да, неявный возвращаемый тип int мог бы уничтожить все здесь. Хорошая жемчужина - person Gaspa79; 25.07.2019

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

struct
{
  float x;
  float y;
} point;

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

person unwind    schedule 24.04.2009

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

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

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

person Stefan Steinegger    schedule 24.04.2009
comment
Итак, требует ли C ++ точка с запятой после каждого объявления? - person Loai Nagati; 25.05.2009
comment
Обратите внимание, что таким образом вы не можете создать объект анонимного класса, а можете наоборот. - person Kevin; 09.11.2014

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

class MyClass
{
.
.
.
} MyInstance;

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

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

person Mykola Golubyev    schedule 24.04.2009

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

struct MyStruct { ... };
class  MyClass  { ... }    //inconsistency
person Zifre    schedule 24.04.2009
comment
А как насчет namespace myNamespace { ... } // inconsistent but valid? - person Chris K; 25.01.2019

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

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

class MyClass{...} MyInstance;

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

class MyClass{...} MyInstance1, MyInstance2;

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

int a, b, c;

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

person Roger Nelson    schedule 25.04.2009
comment
Но определение функции - это тоже утверждение, но без точек с запятой. - person JP Zhang; 02.03.2018