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

Ben*_*key 15 c++ struct

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

struct MyStruct
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

并且还可以执行以下操作:

typedef struct
{
    ...
} MyStruct;
Run Code Online (Sandbox Code Playgroud)

然而就我所知,两者之间没有可辨别的区别.哪个更好?如果没有差异,为什么两种方式都存在?在风格或可读性上,一个比另一个好吗?

Fai*_*ali 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
};
Run Code Online (Sandbox Code Playgroud)

4)您不能使用它来定义嵌套结构

struct S { struct M; };

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

struct S::M { }; // ok
Run Code Online (Sandbox Code Playgroud)

如您所见,两者之间存在明显的差异.typedef的一些怪癖是C兼容性的结果(这主要是为什么我认为两种方式存在) - 并且在大多数情况下,在类头中声明名称是更自然的C++ - 它有其优点(特别是当你需要定义构造函数和析构函数),因此是优选的.如果您正在编写需要与C和C++兼容的代码,那么使用这两种方法都有好处.但是如果你正在编写纯C++,我发现在class-head中指定类名更具可读性.


Dav*_*eau 12

typedef版本是一个特例

typedef foo bar;
Run Code Online (Sandbox Code Playgroud)

它定义了一个新的"类型"栏作为foo的别名.在你的情况下,foo恰好是一个结构.在C中,这是引入新"类型"的唯一方法(在引号中,因为它们实际上并不等同于int,float和co).在C++中,这不是那么有用,因为C++旨在使新类型的定义比C更容易和更完整(至少在C++的开头),并且甚至不需要typedef来引用先前声明的struct(或类).


小智 7

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