到目前为止,名字查找(name lookup)(寻找与所用名字最匹配的过程)的过程比较直接了当:
- 首先,在名字所在的块中寻找其声明语句,只考虑在名字的使用之前出现的声明。
- 如果没有找到,继续查找外层作用域。
- 如果最终没有找到匹配的声明,则程序报错。
对于定义在类内部的成员函数来说,解析其中名字的方式与上述的查找规则有所区别,不过在当前的这个例子中体现的不是太明显。类的定义分为两步处理:
- 首先,编译成员的声明。
- 直到类全部可见后才编译函数体。
按照这种两阶段的方式处理类可以简化类代码的组织方式。因为成员函数体直到整个类可见后才会被处理,所以它能使用类中定义的任何名字。相反,如果函数的定义和成员的声明同时被处理,那么我们将不得不在成员函数中只使用那些已经出现的名字。
用于类成员声明的名字查找
这种两阶段的处理方式只适用于成员函数中使用的名字。声明中使用的名字、包括返回类型或者参数列表中使用的名字,都必须在使用前确保可见。如果某个成员的声明使用了类中尚未出现的名字,则编译器将会在定义该类的作用域中继续查找。例如:
typedef double Money; string bal; class Account { public: Money balance() {return bal;} private: Money bal; //... }
当编译器看到balance的函数声明语句时,它将在Account类的范围内寻找对Money的声明。编译器只考虑Account中在使用Money前出现的声明。