问题非常简单.为了进一步澄清,究竟是什么之间的区别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)
差异很微妙.在第一种情况下,您将创建一个具有名称的类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)