web-dev-qa-db-fra.com

Point-virgule après les accolades de déclaration de classe

Dans les classes C++, pourquoi le point-virgule après l'accolade fermante? Je l'oublie régulièrement et j'obtiens des erreurs de compilation et donc du temps perdu. Cela me semble quelque peu superflu, ce qui est peu probable. Les gens font-ils vraiment des choses comme:

class MyClass
{
.
.
.
} MyInstance;

Je l'obtiens du point de vue de la compatibilité C pour les structures et les énumérations, mais comme les classes ne font pas partie du langage C, je suppose que c'est principalement la cohérence entre les constructions de déclarations similaires.

Ce que je cherchais était plus lié à la logique de conception plutôt qu'à la possibilité de changer quoi que ce soit, bien qu'une bonne complétion de code IDE pourrait piéger cela avant la compilation.

71
SmacL

Le point-virgule après l'accolade fermante dans une déclaration de type est requis par le langage. C'est ainsi depuis les premières versions de C.

Et oui, les gens font effectivement la déclaration que vous venez de faire. Il est utile pour créer des types de portée à l'intérieur des méthodes.

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

  struct ADifferentType { int x; };
}

Dans ce cas, je pense qu'il est clair pourquoi les points-virgules sont nécessaires. Quant à savoir pourquoi il est nécessaire dans le cas plus général de déclarer dans le fichier d'en-tête, je ne suis pas sûr. Mon devinez est que c'est historique et a été fait pour faciliter l'écriture du compilateur.

43
JaredPar

Le lien fourni par @MichaelHaren semble fournir la cause racine . Le point-virgule (comme d'autres l'ont souligné) est hérité de C. Mais cela n'explique pas pourquoi C l'a utilisé en premier lieu. La discussion comprend ce joyau d'un exemple:

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

Les versions plus anciennes de C avaient un type de retour int implicite à partir d'une fonction, sauf indication contraire. Si nous omettons le ; À la fin de la définition de la structure, nous définissons non seulement un nouveau type fred, mais déclarons également que main() renverra une instance de fred. C'est à dire. le code serait analysé comme ceci:

struct fred { int x; long y; } main()
{ 
  return 0; /* invalid return type, expected fred type */
} 
58
Nathan

Je suppose que c'est parce que les classes sont des déclarations, même lorsqu'elles ont besoin d'accolades pour le regroupement. Et oui, il y a l'argument historique selon lequel, en C, vous pourriez faire

struct
{
  float x;
  float y;
} point;

vous devriez pouvoir faire quelque chose de similaire en C++, il est logique que la déclaration class se comporte de la même manière.

15
unwind

C'est court pour

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

Le point-virgule après les accolades de la déclaration de classe est en fait exagéré, mais c'est ainsi que C++ est défini. Le point-virgule après la déclaration de variable est toujours nécessaire et a du sens.

8
Stefan Steinegger

En C/C++, le; est un terminateur d'instruction. Toutes les déclarations se terminent par; pour éviter toute ambiguïté (et pour simplifier l'analyse). La grammaire est cohérente à cet égard. Même si une déclaration de classe (ou n'importe quel bloc d'ailleurs) est longue de plusieurs lignes et est délimitée par {}, il s'agit toujours simplement d'une instruction (le {} fait partie de l'instruction) doit donc se terminer par; (Le; n'est pas un séparateur/délimiteur)

Dans votre exemple

class MyClass{...} MyInstance;

est l'énoncé complet. On pourrait définir plusieurs instances de la classe déclarée dans une seule instruction

class MyClass{...} MyInstance1, MyInstance2;

Ceci est complètement cohérent avec la déclaration de plusieurs instances d'un type primitif dans une seule instruction:

int a, b, c;

La raison pour laquelle on ne voit pas souvent une telle désclaration de classe et d'instance, est-ce que l'instance pourrait? Seulement? être une variable globale, et vous ne voulez pas vraiment souvent des objets globaux à moins qu'ils ne soient des structures statiques et/ou Plain Old Data.

3
Roger Nelson

Je n'utilise pas de telles déclarations

class MyClass
{
.
.
.
} MyInstance;

Mais dans ce cas, je peux comprendre pourquoi le point-virgule est là.
Parce que c'est comme int a; - déclaration de variable.

Probablement pour la cohérence car vous pouvez omettre le point-virgule "MyInstance" qui y reste.

3
Mykola Golubyev

Il est nécessaire après un struct pour des raisons de compatibilité, et comment aimeriez-vous ceci:

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