C++'da 'struct' ve 'typedef struct' arasındaki fark nedir?

C++'da, arasında herhangi bir fark var mı?

struct Foo { ... };

ve

typedef struct { ... } Foo;
Çözüm

C++'da sadece ince bir fark vardır. Bu C'den kalan bir şeydir ve bir fark yaratır.

C dili standardı (C89 §3.1.2.3, C99 §6.2.3 ve C11 §6.2.3), tag tanımlayıcıları (struct/union/enum için) ve sıradan tanımlayıcılar (typedef ve diğer tanımlayıcılar için) dahil olmak üzere farklı tanımlayıcı kategorileri için ayrı ad alanlarını zorunlu kılar.

Eğer sadece söyleseydin:

struct Foo { ... };
Foo x;

derleyici hatası alırsınız, çünkü Foo yalnızca etiket isim alanında tanımlanmıştır.

Bunu şu şekilde beyan etmeniz gerekir:

struct Foo x;

Ne zaman bir Fooya atıfta bulunmak isteseniz, onu her zaman bir struct Foo olarak adlandırmanız gerekir. Bu hızlı bir şekilde can sıkıcı hale gelir, bu yüzden bir typedef ekleyebilirsiniz:

struct Foo { ... };
typedef struct Foo Foo;

Artık struct Foo (etiket isim alanında) ve sadece Foo (sıradan tanımlayıcı isim alanında) aynı şeyi ifade eder ve struct anahtar sözcüğü olmadan Foo türünde nesneleri serbestçe bildirebilirsiniz.


Yapı:

typedef struct Foo { ... } Foo;

sadece bildirim ve typedef için bir kısaltmadır.


Sonunda,

typedef struct { ... } Foo;

anonim bir yapı bildirir ve bunun için bir typedef oluşturur. Böylece, bu yapı ile etiket isim alanında bir isme sahip olmaz, sadece typedef isim alanında bir isme sahip olur. Bu aynı zamanda ileri-beyan edilemeyeceği anlamına gelir. Eğer bir ileri bildirim yapmak istiyorsanız, ona etiket isim alanında bir isim vermelisiniz.


C++'da, tüm struct/union/enum/class bildirimleri, isim aynı isimde başka bir bildirim tarafından gizlenmediği sürece, örtük olarak typedef'miş gibi davranır. Tüm detaylar için Michael Burr'un cevabına bakınız.

Yorumlar (16)

Arada bir fark var, ama ince bir fark. Şu şekilde bakın: struct Foo yeni bir tip sunar. İkincisi, isimsiz bir struct türü için Foo adında (yeni bir tür değil) bir takma ad oluşturur.

7.1.3 typedef belirteci

1 [...]

typedef belirticisi ile bildirilen bir ad, bir typedef-adı olur. Bildiriminin kapsamı içinde, bir typedef-name sözdizimsel olarak bir anahtar sözcüğe eşdeğerdir ve tanımlayıcı ile ilişkili türü Madde 8'de açıklanan şekilde. Dolayısıyla, bir typedef ismi başka bir tipin eşanlamlısıdır. Bir typedef-name sınıf bildirimi (9.1) veya enum bildirimi gibi yeni bir tür tanıtmaz.

8 Eğer typedef bildirimi isimsiz bir sınıf (veya enum) tanımlıyorsa, bildirim tarafından bildirilen ilk typedef ismi sınıf tipinin (veya enum tipinin) bağlantı için sınıf tipini (veya enum tipini) belirtmek için kullanılması sadece amaçlar (3.5). [ Örnek:

typedef struct { } *ps, S; // S is the class name for linkage purposes

Dolayısıyla, bir typedef her zaman başka bir tür için yer tutucu/eşanlamlı olarak kullanılır.

Yorumlar (0)

C++'da bir fark yoktur, ancak C'de struct Foo'nun örneklerini açıkça yapmadan bildirmenize izin vereceğine inanıyorum:

struct Foo bar;
Yorumlar (1)