2009-07-05 3 views
15

В C++ можно создать на структуру:Цель структуры, ЬурейеЕ структуры, в C++

struct MyStruct 
{ 
    ... 
} 

А также можно сделать следующее:

typedef struct 
{ 
    ... 
} MyStruct; 

И еще, насколько я может сказать, никакой заметной разницы между ними. Что предпочтительнее? Почему оба пути существуют, если нет разницы? Является ли лучше, чем другой по стилю или читабельности?

+2

Это дубликат http://stackoverflow.com/questions/612328/difference-between -struct-and-typedef-struct-in-c, но я не собираюсь голосовать за закрытие, потому что принятый ответ на этот вопрос (тонко) ошибочен, как объяснялось во втором голосовавшем ответе ... –

ответ

12

ЬурейеЕ версия представляет собой частный случай

typedef foo bar; 

, который определяет новый «тип» бар в качестве псевдонима для Foo. В вашем случае foo оказывается структурой. В C это был единственный способ ввести новые «типы» (в кавычках, потому что они на самом деле не эквивалентны int, float и co). В C++ это не так полезно, потому что C++ был разработан, чтобы сделать определение новых типов более легким и более полным, чем C (по крайней мере, в начале C++), и typedef даже не нужно ссылаться на ранее объявленную структуру (или класс).

+1

в этом case foo также является неназванной структурой –

+0

Ri GHT. и 'MyStruct' будет использоваться для целей привязки: вы, например, найдете, что компилятор будет использовать его для искажения имен его функций-членов. –

+0

@David - yes - while typedef создает полезное имя для неназванного типа, есть заметные последствия для использования typedef - см. Мой ответ для деталей :) –

2

Вы должны использовать typedef, поэтому вам не нужно указывать ключевое слово struct при объявлении переменных этой структуры.

Без ЬурейиЙ:

struct MyStruct foo; 

С ЬурейиМ:

MyStruct foo; 

В основном вы делаете MyStruct появляется как новый тип так же реализует определенный уровень типа абстракции, как программистам не нужно знать явно, какой это тип. Вы можете передать MyStruct в функцию, манипулировать данными в ней и вернуть ее, и программисту не нужно беспокоиться о том, что на самом деле происходит.

Значительная часть стандартной библиотеки C использует typedefs по этой причине.

+0

поэтому его просто не печатайте? – darkrain

+5

не нужно для ключевого слова 'struct' в C++, только C –

+0

Ах, извините, всегда бывает, когда программисты C участвуют в вопросах C++ :(Но вы поймали ответ, прежде чем я закончил его редактирование :). – Cromulent

7

Последний совместим с C - используйте первый в новом коде C++.

0

«struct MyStruct {};" Конструкция неявно определяет эквивалентный typedef, поэтому обычно это будет предпочтительным современным использованием. Есть еще некоторые виды использования для typedef, в основном с типами указателей для структур. Например.

typedef struct MyStruct* MyStructPtr; 
22

Вот различие между этими двумя декларациями/определениями:


1) Вы не можете использовать ЬурейеЕ имя для идентификации конструктора или деструктора

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) Вы не можете скрыть имя typedef, как вы можете имя, введенное через класс-руководитель, или, наоборот, если у вас уже есть функция или объект с определенным именем, вы все равно можете объявить класс с этим именем, используя класс-голова, но не с помощью метода typedef.

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) Вы не можете использовать имя ЬурейеЕ в уточненной спецификатор типа

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) Вы не можете использовать его, чтобы определить вложенное Структуры

struct S { struct M; }; 

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

struct S::M { }; // ok 

Как вы можете видеть, существует заметная разница между ними. Некоторые из причуд typedefs являются результатом совместимости C (что в основном связано с тем, что оба пути существуют, я считаю) - и в большинстве случаев объявление названия в классе-голове более естественное C++ - оно имеет свои преимущества (особенно когда вы необходимо определить конструкторы и деструкторы), и поэтому предпочтительнее. Если вы пишете код, который должен быть совместимым с C и C++, тогда есть преимущество в использовании обоих подходов. Но если вы пишете чистый C++, я считаю, что определение имени класса в классе-голове должно быть более читаемым.

+0

Wow! Спасибо за это :) – Viet

+0

Другим отличием было бы в определении имени функций внутри этих структур или получении их или указателей на них в качестве параметров. – CesarB

+0

@CesarB - ну по стандарту имя typedef действительно используется для целей привязки, если не указано другое имя, поэтому я не вижу, как он отличается - возможно, вы можете привести пример? –

1

Есть много ответов, которые рассматривают оба подхода как эквивалентные, но они не являются.

Ключевое слово typedef используется для создания псевдонима типа, то есть оно предоставляет новый способ обращения к другому типу. Когда вы используете typedef struct {} XXX;, вы фактически создаете неназванный тип, а затем создаете псевдоним XXX для этого неназванного типа. С другой стороны, когда вы вводите struct XXX {}.

Пожалуйста, прочитайте ответ Майкл Барр here (который является лучшим ответом, чем тот, принятый на этот вопрос.

Смежные вопросы