2011-10-08 6 views
5

Powiel możliwe:
In C++ classes, why the semi-colon after the closing braceC++ Średnik po klasie, struct, enum, ... bezużyteczne, ale kompilatory nadal emitują błędy?

To jest coś, czego nie zastanawiał się przez jakiś czas, to dlaczego trzeba umieścić średnik po nawiasie zamykającym klasa, struct lub wyliczać w C++?

Gorsze (lub faktyczne pytanie), dlaczego kompilatory emitują błędy na ich temat, gdy mogą po prostu wydać ostrzeżenie?

Czy to naprawdę ważne, aby wstawić tam ten średnik i dlaczego?

Odpowiedz

10

To jest resztka z C. Możesz zadeklarować zmienne po deklaracji cladd/struct/enum. kod:

class A{}; 
A a; 

jest identyczna:

class A{} a; 

Kompilator potrzebuje ; wiedzieć nie chcą deklarować zmienne po deklaracji klasy.

2

dlaczego trzeba wstawić średnik po nawiasie zamykającym klasy, struct lub enum w C++?

Prawdziwa odpowiedź, ponieważ tak mówi standard C++. Język został zaprojektowany w taki sposób, aby każda deklaracja kończyła się na ;.

Obiekt klasy mogą być zadeklarowane jako:

class MyClass 
{ 
    //Members  
}obj; 

a więc ; na końcu zastrzału.

Gorsze (lub faktyczne pytanie), dlaczego kompilatory emitują błędy na jego temat, gdy mogą po prostu wydać ostrzeżenie?

Kompilator generuje ostrzeżenie, gdy wątpi coś może być źle lub potencjalnie niebezpieczne

Kompilator wystawia błąd, gdy program nie przestrzega składniowe wytycznymi określonymi w normie, opuszczono ŚREDNIK w wymienionych przypadkach narusza reguły składni wymienione w standardzie C++, a tym samym błąd.

8

Czy to naprawdę ważne, aby wstawić tam ten średnik i dlaczego?

Tak. To może być przydatne kiedyś.

Można zdefiniować struct, i może zadeklarować obiekt jako:

struct A 
{ 
    //members 
} obj; 

obj jest obiektem typu A i zadeklarować to tak jak pokazano powyżej. To właśnie w ten sam sposób można umieścić średnik po zmiennych deklarujących, takie jak:

int i;      //declares i of type int 
std::string s;    //declares s of type std::string 
struct {int x,y,z;} point; //declares point of an unnamed struct type 

dwa Oto pierwsze deklaracje wyglądają bardzo znajomo, ale ostatni wygląda nieco nieznane, jak to określa się na anonimowe struct, a jednocześnie deklaruje obiektu o nazwie point nienazwanej struktury.

W dolnej linii umieszczamy średnik po zadeklarowaniu obiektów równomiernie, bez względu na sposób deklarowania obiektów, bez względu na ich typ.

Nie tylko, że można nawet typedef w jednolity sposób:

typedef int my_int; 
typedef std::string my_string; 
typedef struct {int x,y,z;} my_point; 

Teraz wszystkie te my_int, my_string, a my_point są typy.

Ale kiedy nie wykonujesz żadnej z nich (tzn. Nie deklarujesz obiektów, ani nie określasz typedefs), po prostu opuszczasz miejsce jako takie, puste, bez deklaracji/definicji. Ale należy zauważyć, że daje on interesującą i użyteczną funkcję przez cały czas.

3

Definicje klas, struktur i wyliczeń są następujące: definicje. Definicje w C++, podobnie jak w C, muszą być zakończone średnikiem. Jeśli nie umieścić go tam byłoby dużo niejasności:

struct X 
{ 
} //no ; 
foo() //no return value 
{ 
} 

ten jest odczytywany jako funkcja foo zwracającej struct, a nie struct i funkcję, która zwraca liczbę całkowitą(), pominięte. To jest poprawna C, ale nie C++.

int *x; 
void foo() 
{ 
    struct S { } //no ; 
    *x = 3; // <--- what is this? 
} 

jest drugim x lokalna zmienna typu pointer-to-S, czy też jest to odniesienie do globalnej x? Po prostu nie możesz powiedzieć.

Istnieje wiele innych przykładów, prawdopodobnie można pomyśleć kilka, jeśli spróbujesz.

+0

Definicje funkcji nie wymagają średnika i nadal są liczone jako definicje. –

+0

Prawda, podobnie jak przestrzenie nazw. Tak, trochę nadgubkulowałem ... – rodrigo