我用C ++编程了很长一段时间,直到今天我才想到这一点。
请考虑以下代码:
struct foo
{
// compiles fine
void bar()
{
a = 1;
my_int_type b;
b = 5;
}
// Just a declaration, this fails to compile, which leads me to assume that
// even though the bar() method is declared and defined all at once, the
// compiler looks/checks-syntax-of the class interface first, and then compiles
// the respective definitions...?
void bar2(my_int_type); // COMPILE ERROR
my_int_type b; // COMPILE ERROR because it comes before the typedef declaration
typedef int my_int_type;
my_int_type a;
void bar3(my_int_type); // compiles fine
};
int main()
{
foo a;
a.bar();
return 0;
}
我是否理解错误发生的原因(请参阅上面的bar2()
评论)是否正确/不正确?无论哪种方式,我都希望能够简单地概述单通C ++编译器如何编译上面给出的代码。
答案 0 :(得分:10)
在大多数情况下,C ++文件是从上到下解析的,因此必须在使用实体之前声明它们。
在您的课程中,bar2
和b
无效,因为它们都使用了尚未声明的my_int_type
。
“自上而下”解析规则的一个例外是在其类定义中定义的成员函数。解析这样的成员函数定义时,它会被解析为好像它出现在类的定义之后。这就是您在my_int_type
中使用bar
有效的原因。
实际上,这是:
struct foo
{
void bar()
{
my_int_type b;
}
typedef int my_int_type;
};
与:
相同struct foo
{
void bar();
typedef int my_int_type;
};
inline void foo::bar()
{
my_int_type b;
}
答案 1 :(得分:5)
编译器刚刚开始陷入困境。任何不熟悉的符号都将被视为未定义的新符号。这是函数定义或头文件背后的方案。
您可以假设编译器首先创建定义列表,因此bar()方法应该正确编译,因为之前已经提供过定义。
答案 2 :(得分:3)
它与可见性有很大关系。我认为你的困惑可能来自假设一次通过。可以将类解析分为两个阶段。
这样做的好处是我们可以从类成员函数中看到整个类。