在C ++中,可以创建一个结构:
struct MyStruct
{
...
}
还可以执行以下操作:
typedef struct
{
...
} MyStruct;
然而据我所知,两者之间没有明显区别。哪个更好?如果没有差异,为什么两种方式都存在?在风格或可读性上,一个比另一个好吗?
答案 0 :(得分:22)
以下是两个声明/定义之间的区别:
1)您不能使用typedef名称来标识构造函数或析构函数
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名称,就像您可以通过class-head引入名称一样 - 或者相反,如果您已经有一个函数或具有特定名称的对象,您仍然可以使用该名称声明具有该名称的类。 class-head但不是通过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)您不能在详细的类型说明符
中使用typedef名称
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
正如您所看到的,两者之间存在明显差异。 typedef的一些怪癖是C兼容性的结果(这主要是为什么我认为存在这两种方式) - 并且在大多数情况下,在类头中声明名称是更自然的C ++ - 它有其优点(特别是当你需要定义构造函数和析构函数),因此是优选的。如果您正在编写需要与C和C ++兼容的代码,那么使用这两种方法都会带来好处。但是如果你正在编写纯C ++,我会发现在class-head中指定类名更具可读性。
答案 1 :(得分:12)
typedef版本是
的特例typedef foo bar;
将新的“type”栏定义为foo的别名。在你的情况下,foo恰好是一个结构。在C中,这是引入新“类型”的唯一方法(在引号中,因为它们实际上并不等同于int,float和co)。在C ++中,这不是那么有用,因为C ++旨在使新类型的定义比C更容易和更完整(至少在C ++的开头),并且甚至不需要typedef来引用先前声明的struct(或类)。
答案 2 :(得分:7)
后者与C兼容 - 在新的C ++代码中使用第一个。
答案 3 :(得分:2)
您将使用typedef,因此在声明该结构的变量时不需要指定struct关键字。
没有typedef:
struct MyStruct foo;
使用typedef:
MyStruct foo;
基本上你正在使MyStruct显示为一个新类型,所以它也实现了某种程度的类型抽象,因为程序员不需要明确知道它是什么类型。你可以将MyStruct传递给一个函数,操纵它中的数据并返回它,程序员不必担心实际发生的事情。
出于这个原因,许多C标准库都使用typedef。
答案 4 :(得分:0)
“struct MyStruct {};”构造隐式定义了等效的typedef,因此通常这是首选的现代用法。对于typedef仍然有一些用途,主要是指向结构的指针类型。 E.g。
typedef struct MyStruct* MyStructPtr;
答案 5 :(得分:0)
有许多答案认为两种方法都是等价的,但事实并非如此。
typedef
关键字用于创建类型别名,也就是说,它提供了一种引用另一种类型的新方法。当您使用typedef struct {} XXX;
时,实际上是在创建一个未命名的类型,然后为该未命名的类型创建别名 XXX 。另一方面,当您键入struct XXX {}
。
请阅读Michael Burr的答案here(这个答案比该问题所接受的答案更好。