Verschil tussen 'struct' en 'typedef struct' in C++?
In C++, is er enig verschil tussen:
struct Foo { ... };
en
typedef struct { ... } Foo;
796
3
In C++, is er enig verschil tussen:
struct Foo { ... };
en
typedef struct { ... } Foo;
In C++ is er slechts een subtiel verschil. Het is een overblijfsel van C, waarin het een verschil maakt.
De C taal standaard (C89 §3.1.2.3, C99 §6.2.3, en C11 §6.2.3) mandateert aparte namespaces voor verschillende categorieen identifiers, inclusief tag identifiers (voor
struct
/union
/enum
) en gewone identifiers (voortypedef
en andere identifiers).Als je gewoon zou zeggen:
zou je een compilerfout krijgen, omdat
Foo
alleen in de tag namespace gedefinieerd is.Je'zou het moeten declareren als:
Elke keer als je naar een
Foo
wilt verwijzen, moet je het altijd eenstruct Foo
noemen. Dit wordt snel vervelend, dus je kunt eentypedef
toevoegen:Nu verwijzen
struct Foo
(in de tag namespace) en gewoonFoo
(in de gewone identifier namespace) allebei naar hetzelfde, en kun je objecten van het typeFoo
vrij declareren zonder hetstruct
keyword.De construct:
is gewoon een afkorting voor de declaratie en
typedef
.Tenslotte,
declareert een anonieme structuur en creëert er een
typedef
voor. Met deze constructie heeft het dus geen naam in de tag namespace, maar alleen een naam in de typedef namespace. Dit betekent dat het ook niet forward-declared kan worden. Als je een forward-declared wilt maken, moet je het een naam geven in de tag namespace.In C++ gedragen alle
struct
/union
/enum
/class
declaraties zich alsof ze impliciettypedef
'ed zijn, zolang de naam niet verborgen wordt door een andere declaratie met dezelfde naam. Zie Michael Burr's antwoord voor de volledige details.Er is een verschil, maar subtiel. Bekijk het zo:
struct Foo
introduceert een nieuw type. De tweede creëert een alias genaamd Foo (en niet een nieuw type) voor een naamloosstruct
type.Een typedef wordt dus altijd gebruikt als een placeholder/synoniem voor een ander type.
Er is geen verschil in C++, maar ik geloof dat je in C instanties van de struct Foo kunt declareren zonder het expliciet te doen: