Крапка з комою після фігурних дужок


82

Чому в класах С ++, чому крапка з комою після закриваючої дужки? Я регулярно забуваю про це і отримую помилки компілятора, а отже, і втрачений час. Мені здається дещо зайвим, що навряд чи буде так. Чи справді люди роблять такі речі:

class MyClass
{
.
.
.
} MyInstance;

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

Те, що я шукав, було більше пов’язане з обґрунтуванням дизайну, а не з можливістю щось змінити, хоча хороша IDE для завершення коду може затримати це перед компіляцією.


4
Це може допомогти: cpptalk.net/…
Майкл Харен,

@Michael, дякую за посилання. З історичної точки зору це має розумний сенс, і якщо C ++ дозволяє всі граматики C, а класи C ++ є синонімами зі структурами, ми залишаємо необхідну крапку з комою в кінці класу.
SmacL

3
@Brian, ну серйозне питання. Я прекрасно усвідомлюю, що маю з цим жити, але мені цікаво, як обгрунтовуватись розробка та впровадження.
SmacL

Гаразд, але, можливо, вам слід відредагувати своє запитання, щоб включити бажане обґрунтування дизайну. Так воно і є, спонукає людей задавати запитання на кшталт "чому фігурні дужки"? :) Можливо, вам буде цікаво прочитати Дизайн і еволюцію C ++ Stroustrup, хоча він охоплює більш вагомі питання, ніж крапки з комою в кінці занять.
Брайан Ніл,

@Brian, досить справедливо, і це було на межі щодо того, чи потрібно це вікі. Питання було задано після того, як у великій побудові було залишено крапку з комою в регулярно використовуваному заголовку. Це коштувало мені півгодини, звідси візит до SO. Питання відредаговано відповідно до вашої пропозиції.
SmacL

Відповіді:


47

Двокрапка після закриваючої дужки в декларації типу потрібна мові. Так було з найперших версій C.

І так, люди справді роблять декларацію, яку ви щойно там подали. Це корисно для створення типів сфери всередині методів.

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

  struct ADifferentType { int x; };
}

У цьому випадку, я думаю, зрозуміло, навіщо потрібні крапки з комою. Щодо того, навіщо це потрібно, у більш загальному випадку декларування у файлі заголовка я не впевнений. Я припускаю , що це історично і було зроблено для полегшення написання компілятора.


Чому я не можу просто створити тип сфери, не вказавши MyInstance? Це здається дивним, коли ви поєднуєте дві дії: оголошення нового типу та оголошення нової змінної.
Микола Голуб'єв

@Mykola, ти можеш зробити і те, і інше. Див. Зразок, який я додав
JaredPar

72

Посилання надана @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 буде впливати на все тут. Хороший самоцвіт
Гаспа79

17

Я думаю, це тому, що класи є деклараціями, навіть коли їм потрібні фігурні дужки для групування. І так, є історичний аргумент, що оскільки в C ви могли б це зробити

struct
{
  float x;
  float y;
} point;

ви повинні в С ++ робити подібне, має сенс, щоб classдекларація поводилася так само.


11

Це скорочено для

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

Крапка з комою після фігурних дужок оголошення класу насправді є надмірною, але саме так визначається C ++. Крапка з комою після оголошення змінної завжди потрібна і має сенс.


1
Отже, чи потрібна C ++ з комою після кожної декларації?
Loai Nagati

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;

Причиною того, що людина не часто бачить таке декларування класу та екземпляру, є екземпляр? бути глобальною змінною, і ви насправді не часто хочете глобальні об'єкти, якщо вони не є статичними та / або звичайними старими структурами даних.


2
Але визначення функції теж є твердженням, але без крапки з комою.
Jiapeng Zhang 02.03.18
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.