Differenza tra 'struct' e 'typedef struct' in C++?
In C++, c'è qualche differenza tra:
struct Foo { ... };
e
typedef struct { ... } Foo;
796
3
In C++, c'è qualche differenza tra:
struct Foo { ... };
e
typedef struct { ... } Foo;
In C++, c'è solo una sottile differenza. È un retaggio del C, in cui fa la differenza.
Lo standard del linguaggio C (C89 §3.1.2.3, C99 §6.2.3, e C11 §6.2.3) impone spazi dei nomi separati per diverse categorie di identificatori, inclusi tag identifiers (per
struct
/union
/enum
) e ordinary identifiers (pertypedef
e altri identificatori).Se hai appena detto
avreste un errore del compilatore, perché
Foo
è definito solo nello spazio dei nomi dei tag.Dovresti dichiararlo come:
Ogni volta che vuoi fare riferimento a un
Foo
, dovresti sempre chiamarlostruct Foo
. Questo diventa fastidioso velocemente, quindi puoi aggiungere untypedef
:Ora
struct Foo
(nello spazio dei nomi dei tag) e semplicementeFoo
(nello spazio dei nomi degli identificatori ordinari) si riferiscono entrambi alla stessa cosa, e si possono dichiarare liberamente oggetti di tipoFoo
senza la parola chiavestruct
.Il costrutto:
è solo un'abbreviazione per la dichiarazione e il
typedef
.Infine,
dichiara una struttura anonima e crea un
typedef
per essa. Quindi, con questo costrutto, non ha un nome nello spazio dei nomi dei tag, ma solo un nome nello spazio dei nomi typedef. Questo significa che non può nemmeno essere dichiarato in avanti. Se vuoi fare una dichiarazione forward, devi dargli un nome nello spazio dei nomi dei tag.In C++, tutte le dichiarazioni
struct
/union
/enum
/class`` si comportano come se fossero implicitamente
typedef`'ed, finché il nome non è nascosto da un'altra dichiarazione con lo stesso nome. Vedere la risposta di Michael Burr per tutti i dettagli.C'è una differenza, ma sottile. Guardatela in questo modo:
struct Foo
introduce un nuovo tipo. Il secondo crea un alias chiamato Foo (e non un nuovo tipo) per un tipo senza nomestruct
.7.1.3 Lo specificatore typedef**
1 [...]
Un nome dichiarato con lo specificatore typedef diventa un typedef-name. Nell'ambito della sua dichiarazione, un typedef-name è sintatticamente equivalente ad una parola chiave e nomina il tipo associato all'identificatore nel modo descritto nella clausola 8. Un typedef-name è quindi un sinonimo di un altro tipo. Un nome tipografico non introduce un nuovo tipo come fa una dichiarazione di classe (9.1) o di enum.
8 Se la dichiarazione typedef definisce una classe (o enum) senza nome, il primo nome tipografico dichiarato dalla dichiarazione essere quel tipo di classe (o di enum) è usato per denotare il tipo di classe (o di enum) solo per scopi di collegamento (3.5). solo per scopi di collegamento (3.5). [ Esempio:
Quindi, un typedef sempre è usato come segnaposto/sinonimo di un altro tipo.
Non c'è differenza in C++, ma credo che in C vi permetterebbe di dichiarare istanze della struct Foo senza farlo esplicitamente: