"Typedef声明"和"类声明"之间的区别

Zee*_*bit 1 c++ typedef class

问题非常简单.为了进一步澄清,究竟是什么之间的区别Foo1,并Foo2在方式方面在声明中下面的代码(例如,一个采用class Foo1 { ... };,另一个使用typedef class { ... } Foo2;)?

class Foo1 {
public:
    void bar() { }
};

typedef class {
public:
    void bar() { }
} Foo2;

int main()
{
    Foo1 f1;
    f1.bar();
    Foo2 f2;
    f2.bar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 6

差异很微妙.在第一种情况下,您将创建一个具有名称的类Foo1,而在第二种情况下,您将创建一个匿名类并使用a typedef来提供别名Foo2.

第三种选择是:

typedef class Foo3 {
public:
   void bar() {}
} Foo3;
Run Code Online (Sandbox Code Playgroud)

这将创建一个名为的类,Foo3 创建一个别名Foo3来引用它.

细微之处在于如何用语言处理标识符.当代码中存在标识符时,编译器将执行查找以了解其含义.查找将检查每个范围,首先在全局标识符空间中检查大多数符号(不包括用户定义的类型),如果它无法在那里找到标识符,那么它将在用户定义的标识符空间中查找.用户定义的类型属于第二个标识符空间,而typedef-ed名称存在于第一个组中.只有当两个查找都失败时,编译器才会转到下一个封闭范围.

提供一个简单的测试用例,其中差异是值得注意的:

class A {};
typedef class {} B;
typedef class C {} C;
void A();              // correct: no collision
//void B();            // error, identifier B already used with a different meaning!
//void C();            //   "
namespace test {
   void B();
   void C();
   void f() {
      class A a;       // creates variable of type ::A
      A();             // calls function ::A
      B();             // calls function test::B()
      //class B b;     // error: B does not denote a user-defined type name
      C();             // calls function test::C()
      class C c;       // creates variable of type ::C
   }
}
Run Code Online (Sandbox Code Playgroud)