Hensikten med struct, typedef struct, i C ++

stemmer
15

I C ++ er det mulig å lage en struct:

struct MyStruct
{
    ...
}

Og også mulig å gjøre følgende:

typedef struct
{
    ...
} MyStruct;

Og likevel så vidt jeg kan fortelle, ingen merkbar forskjell mellom de to. Som er å foretrekke? Hvorfor begge veier eksistere hvis det ikke er noen forskjell? Er en bedre enn den andre i stil eller lesbarhet?

Publisert på 05/07/2009 klokken 12:13
kilden bruker
På andre språk...                            


6 svar

stemmer
22

Her er forskjellene mellom de to erklæringer / definisjoner:


1) Du kan ikke bruke et typedef navn for å identifisere en konstruktør eller en destructor

struct MyStruct { MyStruct(); ~MyStruct(); }; // ok

typedef struct { MyStructTD(); ~MyStructTD(); } MyStructTD; // not ok

// now consider 
typedef struct MyStruct2 { MyStruct2(); } MyStructTD2; // ok

MyStructTD2::MyStruct2() { } // ok
MyStructTD2::MyStructTD2() { } // not ok

2) Du kan ikke skjule en typedef navn som du kan et navn introdusert via klasse hodet - eller omvendt hvis du allerede har en funksjon eller et objekt med et bestemt navn, kan du likevel erklære en klasse med dette navnet med klasse-head men ikke via typedef tilnærming.

struct MyStruct { }; // ok

typedef struct { } MyStructTD; // ok

void MyStruct() { }  // (1) - ok Hides struct MyStruct
void MyStructTD() { }  // (2) - not-ok - ill-formed

//> Or if you flip it around, consider in a new translation unit:

void MyStruct() { }   // ok
void MyStructTD() { }   // ok

struct MyStruct { }; // ok
typedef struct { } MyStructTD; // Not ok

3) Du kan ikke bruke et typedef navn i en utdypet typebeskrivelse

struct MyStruct {  }; // ok

typedef struct { } MyStructTD; // ok

int main()
{
  void MyStruct(); 
  void MyStructTD(); // ok - new declarative region

  struct MyStruct ms; // ok - names the type
  struct MyStructTD ms2; // not ok - cannot use typedef-name here

}

struct AnotherStruct 
{ 
    friend struct MyStruct;  // ok
    friend struct MyStructTD; // not ok
};

4) Du kan ikke bruke den til å definere nestede structs

struct S { struct M; };

typedef struct { } S::M;  // not ok

struct S::M { }; // ok

Som du kan se, det er en merkbar forskjell mellom de to. Noen av de quirks av typedefs er et resultat av C kompatibilitet (som hovedsakelig er derfor begge veier eksisterer tror jeg) - og i de fleste tilfeller, erklære navnet i klassen-hodet er mer naturlig C ++ - det har sine fordeler (spesielt når du må definere konstruktører og destructors), og er derfor å foretrekke. Hvis du skriver kode som må være C og C ++ kompatible, så er det fordel å bruke begge tilnærminger. Men hvis du skriver ren C ++, finner jeg spesifiserer navnet klassen i klassen-head å være mer lesbar.

Svarte 05/07/2009 kl. 14:49
kilden bruker

stemmer
12

Den typedef versjonen er et spesialtilfelle av

typedef foo bar;

som definerer en ny "type" bar som et alias for foo. I ditt tilfelle, skjer foo å være en struct. I C, var dette den eneste måten å introdusere nye "typer" (i anførselstegn, fordi de er egentlig ikke tilsvarer int, float og co). I C ++, er dette ikke så nyttig, fordi C ++ er designet for å gjøre definisjon av nye typer lettere og mer fullstendig enn C (i det minste ved begynnelsen av C ++), og den typedef er ikke engang nødvendig å referere til et tidligere erklært struct ( eller klasse).

Svarte 05/07/2009 kl. 12:21
kilden bruker

stemmer
7

Den sistnevnte er der for kompatibilitet med C - bruke den første i nye C ++ kode.

Svarte 05/07/2009 kl. 12:19
kilden bruker

stemmer
2

Du ville bruke en typedef slik at du ikke trenger å spesifisere struct nøkkelordet når erklære variabler som struct.

Uten typedef:

struct MyStruct foo;

Med typedef:

MyStruct foo;

I utgangspunktet er du gjør MyStruct vises som en ny type så det også implementerer noen grad av typen abstraksjon som programmerere ikke trenger å vite eksplisitt hvilken type det er. Du kan sende MyStruct inn en funksjon, manipulere dataene i den og returnere den og programmerer trenger aldri bekymre deg om hva som faktisk skjer.

Mye av C standard bibliotek bruker typedefs på grunn av dette.

Svarte 05/07/2009 kl. 12:16
kilden bruker

stemmer
1

Det er mange svar som vurderer begge tilnærminger som tilsvarende, men de er ikke.

Den typedefnøkkelordet brukes til å skape en type alias, det vil si, det gir en ny måte å henvise til en annen type. Når du bruker typedef struct {} XXX;du faktisk lage en ikke navngitt type og deretter opprette et alias XXX til at ikke navngitte type. På den annen side, når du skriver struct XXX {}.

Vennligst les svaret ved Michael Burr her (som er et bedre svar enn en akseptert for det spørsmålet.

Svarte 05/07/2009 kl. 20:45
kilden bruker

stemmer
0

Den "struct MyStruct {};" konstruere implisitt definerer tilsvarende typedef, så ofte som ville være den foretrukne moderne bruk. Det er fortsatt noen bruksområder for en typedef, hovedsakelig med peker typer til strukturer. Eg

typedef struct MyStruct* MyStructPtr;
Svarte 05/07/2009 kl. 12:20
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more