首页 > 代码库 > 名字查找

名字查找

  定义:寻找与所用名字最匹配的声明的过程

    1. 首先,在名字所在的块中寻找其他声明语句,只考虑在名字的使用之前出现的声明(确认是否是局部变量)

    2. 如果没找到,继续查找外围作用域,继续向其他地方扩散寻找,确认是否是全局变量

    3. 如果最后还是没有找到,那么程序会报错

    对于定义在类内部的成员函数来说,解析规则有所区别, (1) 首先,编译成员的声明 (2) 直到类全部可见后才编译函数体。 按照这种两阶段的方式处理类可以简化类代码的组织方式,因为成员函数体

      直到整个类可见后才会被处理,所以它能使用类中定义的所有名字,相反,如果函数的定义和成员的声明被同时处理,那么我们将不得不在成员函数中只使用那些已经出现的名字,

    这种两阶段的处理方式只适用于成员函数中使用的名字,声明中使用的名字,包括返回类型或者参数列表中使用的名字,都必须在使用前确保可见,如果某个成员的声明

      使用了类中尚未出现的名字,则编译器将会在定义该类的作用域继续查找

    例子:typedef double Money;      //当编译器看到balance函数的声明语句时,它将在Account类的范围内寻找对Money的声明,编译器只考虑Account中在使用Money前出现的声明,

       string bal;            //所以在private中定义的是无效的,因为没找到匹配的成员,所以编译器会在Account的外层继续查找,在这个例子中,编译器会找到typedef声明的Money

       class Account {          //该类型被作为balance函数的返回类型以及数据成员bal的类型,另一方面,balance函数体在整个类可见后才被处理,因此,该函数的return语句

        public:            //返回名为bal的成员而非外层作用域的string对象

        Money balance(){return bal;}

        private:

        Money bal;

       }

    类型名要特殊处理:一般内层作用域可以重新定义外层作用域中的名字,即使该名字已经在内层作用域中使用过,然而在类中如果成员使用了外层作用域中的某个名字,而该名字代表一种数据类型,

    则类不能在之后重新定义该名字,尽管重新定义的类型与外层定义的类型完全一致也不行,

    函数的参数列表中的变量最好不要与类成员变量重名,当重名之后如果想使用类成员变量,那么可以通过this->或类作用域来强制访问类成员   

名字查找