9

Разница между 'struct' и 'typedef struct' в C++?

13

В C++ есть ли разница между следующими определениями:

struct Foo { ... };

и:

typedef struct { ... } Foo;

Дело в том, что оба варианта, похоже, создают тип с именем Foo, но могут ли они иметь какие-либо различия в функциональности или использовании? Является ли использование typedef обязательным в C++ для работы со структурами, или достаточно просто определить структуру с именем? Буду признателен за объяснение!

4 ответ(ов)

0

Одно важное отличие заключается в том, что typedef нельзя предварительно объявить. Поэтому для использования typedef вам необходимо #include файл, содержащий этот typedef, что означает, что все файлы, которые делают #include ваш .h, также включают этот файл, даже если он им не нужен, и так далее. Это может значительно повлиять на время сборки в крупных проектах.

Без использования typedef в некоторых случаях вы можете просто добавить предварительное объявление struct Foo; в верхней части вашего .h файла и включить определение структуры только в вашем .cpp файле.

0

Да, разница действительно существует, но она тонкая. Посмотрите на это так: struct Foo вводит новый тип. Во втором случае создаётся псевдоним с именем Foo (а не новый тип) для анонимного типа struct.

Вот что говорится в стандарте:

7.1.3 Спецификатор typedef

1 [...]

Имя, объявленное с помощью спецификатора typedef, становится именем типа. В пределах области его объявления имя типа синтаксически эквивалентно ключевому слову и обозначает тип, связанный с идентификатором, как описано в разделе 8. Таким образом, имя типа является синонимом другого типа. Имя типа не вводит новый тип, как это делает объявление класса (9.1) или перечисления.

Если декларация typedef определяет анонимный класс (или перечисление), то первое имя типа, объявленное в этой декларации, будет использоваться для обозначения класса (или перечисления) исключительно для целей линковки (3.5). Например:

typedef struct { } *ps, S; // S - это имя класса для целей линковки

Таким образом, typedef всегда используется как заместитель/синоним для другого типа.

0

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

Вот пример:

typedef struct {
    int one;
    int two;
} myStruct;

Попытка сделать предварительное объявление таким образом не сработает:

struct myStruct; // предварительное объявление не сработает

void blah(myStruct* pStruct);

// ошибка C2371: 'myStruct' : переопределение; разные базовые типы

Это происходит потому, что myStruct — это псевдоним для анонимного типа, и компилятор не знает, как обрабатывать такое предварительное объявление. Чтобы исправить это, вам нужно использовать имя для структуры в объявлении. Например:

struct MyStruct {
    int one;
    int two;
};
typedef struct MyStruct myStruct;

void blah(myStruct* pStruct);

Теперь компилятор сможет распознать как struct MyStruct, так и myStruct, и ошибок не возникнет.

0

Важное отличие между typedef struct и struct в C++ заключается в том, что инициализация членов в typedef struct не будет работать.

// 'x' в этом структуре НЕ будет инициализировано в ноль
typedef struct { int x = 0; } Foo;

// 'x' в этой структуре БУДЕТ инициализировано в ноль
struct Foo { int x = 0; };

Причина в том, что в C++ C++11 и позже, стандарт поддерживает инициализацию членов класса непосредственно внутри объявления структуры, но для typedef struct эта возможность не реализована. Это связано с тем, что typedef struct фактически создает алиас для структуры, определенной на уровне C, где такие инициализации отсутствуют.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь