struct,typedef struct的目的,在C ++中

Purpose of struct, typedef struct, in C++

在C++中,可以创建一个结构:

1
2
3
4
struct MyStruct
{
    ...
}

也可以执行以下操作:

1
2
3
4
typedef struct
{
    ...
} MyStruct;

但据我所知,两者之间没有明显的区别。哪个更好?如果没有区别,为什么两者都存在?在样式或可读性方面,一个比另一个好吗?


以下是两种声明/定义之间的区别:

1) You cannot use a typedef name to identify a constructor or a destructor

1
2
3
4
5
6
7
8
9
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) You cannot hide a typedef name like you can a name introduced via the class-head - or conversely if you already have a function or an object with a certain name, you can still declare a class with that name using the class-head but not via the typedef approach.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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) You cannot use a typedef name in an elaborated type specifier

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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) You cannot use it to define nested structs

1
2
3
4
5
struct S { struct M; };

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

struct S::M { }; // ok

正如你所看到的,两者之间有着明显的区别。Type的一些怪癖是C兼容性的结果(这主要是为什么我相信这两种方式)-并且在大多数情况下,在类头中声明名称更自然的C++——它有它的优势(特别是当你需要定义构造函数和析构函数)时,因此是可取的。如果您编写的代码需要是C和C++兼容的,那么使用这两种方法都是有益的。但是如果您编写纯C++,我发现指定类头中的类名更可读。


typedef版本是

1
typedef foo bar;

它将新的"类型"栏定义为foo的别名。在您的例子中,foo恰好是一个结构。在C语言中,这是引入新"类型"的唯一方法(在引号中,因为它们实际上并不等同于int、float和co)。在C++中,这并不是很有用,因为C++被设计成使新类型的定义比C更容易和更完整(至少在C++开始时),并且TyPIFF甚至不需要引用先前声明的结构(或类)。


后者与C兼容,使用新C++代码中的第一个。


您将使用typedef,因此在声明该结构的变量时不需要指定struct关键字。

不带typedef:

1
struct MyStruct foo;

使用TyPulf:

1
MyStruct foo;

基本上,您使mystruct看起来是一种新类型,因此它也实现了某种级别的类型抽象,因为程序员不需要明确地知道它是什么类型。你可以将mystruct传递到一个函数中,操纵函数中的数据并返回它,程序员不必担心实际发生的事情。

因此,许多C标准库都使用typedef。


有许多答案认为这两种方法都是等效的,但事实并非如此。

typedef关键字用于创建类型别名,也就是说,它提供了引用另一个类型的新方法。使用typedef struct {} XXX;时,实际上是在创建一个未命名类型,然后为该未命名类型创建一个别名xxx。另一方面,当你输入struct XXX {}时。

请在这里读一下迈克尔·伯尔的回答(这比那个问题的答案更好)。


"struct mystruct"结构隐式定义了等效typedef,因此通常这是首选的现代用法。typedef还有一些用途,主要是用于结构的指针类型。例如。

1
typedef struct MyStruct* MyStructPtr;