名字查找

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

    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->或类作用域来强制访问类成员   

时间: 2024-11-06 14:08:05

名字查找的相关文章

模板中的名字查找问题

问题起源 先看下面很简单的一小段程序. `#include <iostream>` template <typename T> struct Base { void fun() { std::cout << "Base::fun" << std::endl; } }; template <typename T> struct Derived : Base<T> { void gun() { std::cout &l

类作用域中名字查找的思考(《C++ primer》第四版P382)

1.问题的引入 1).观察以下第一块代码: #include <iostream> using namespace std; class Screen{ public: void test(){ dummy_fcn( ); } void dummy_fcn( ){ } }: 此代码编译无错误............... 2).再看以下第二块代码: #include <iostream> using namespace std; void test(){ dummy_fcn( );

C++ Primer笔记3_默认实参_类初探_名字查找与类的作用域

1.默认函数实参 在C++中,可以为参数指定默认值,C语言是不支持默认参数的,Java也不支持! 默认参数的语法与使用: (1)在函数声明或定义时,直接对参数赋值.这就是默认参数: (2)在函数调用时,省略部分或全部参数.这时可以用默认参数来代替. 注意事项: (1)函数默认值只能赋值一次,或者是在声明中,或者是在定义中,都可以. (2)默认参数定义的顺序为自右到左.即如果一个参数设定了缺省值时,其右边的参数都要有缺省值.比如int f(int a, int b=1,int c=2,int d=

名字查找先于类型检查:函数重载与作用域

作用域屏蔽名字:内层作用域中声明的名字将隐藏外层作用域中声明的同名实体. 同名??C++有关同名的除了变量之外,也就是函数重载了!! [作用域对于函数重载的限制] 1. 在不同的作用域中无法重载函数名 2. 函数匹配时,编译器首先寻找对该函数名的声明,一旦在当前作用域中找到了所需的名字,编译器就会忽略掉外层作用域中的同名实体,剩下的工作就是检查函数调用是否有效了 #include <iostream> using namespace std; void print(double); void

C++名字查找和重载

重载函数的定义:在同一作用域内的几个函数名字相同但形参列表不同,称为重载函数.这里有一个重要的前提就是:同一个作用域: 而如果重载函数是定义在不同的作用域,那么一旦编译器在当前作用域找到所需的名字,编译器就会忽略掉外层作用域中的同名实体.剩下的工作就是在检查函数调用是否有效. 因为这C++中,名字的查找发生在类型检查之前,如果在当前作用域找到了名字,若是有多个名字,进行参数匹配.如果当前作用域只有一个名字,则会直接忽略外层作用域,直接进行类型检查. 类的继承体系也符合这种情况,因此除了覆盖继承而

C++中名字隐藏,名字查找优先于类型检查

题目 C++中名字隐藏是什么? 解答 让我们通过一个例子来讲解C++中的名字隐藏.在C++中,如果一个类里有一个重载的方法, 你用另一个类去继承它并重写(覆盖)那个方法.你必须重写所有的重载方法, 否则未被重写的方法会因为名字相同而被隐藏,从而使它在派生类中不可见. 请看例子: class FirstClass{ public: virtual void MethodA(int); virtual void MethodA(int, int); }; void FirstClass::Metho

条件判断之if、case语句和文件查找命令

一.脚本编程 1.if语句怎样用 人生面临许多选择,在编程世界里同样也有许多选择.同其他编程语言一样,当我们想写一个功能健壮的脚本时,通过条件判断来选择适合的操作尤为重要.在我们执行某些重要的操作之前,判断当前环境是否适合执行这一操作是非常重要的.我们可以用&&和||来做简单的判断,不过shell有更用的语句.shell有两种常见的条件选择语句if和case.我们先来看一下if该怎样用吧. if语句的单分支语法: if 条件判断 ;then;执行命令:fi [[email protecte

linux笔记八---------文件查找

1.find文件查找指令 > find  目录  参数 参数值,参数 参数值.....    > find  /  -name  passwd   //从系统根目录开始递归查找name=passwd的文件    参数        -maxdepth  n  查找目录最深层次        -mindepth  n  查找目录最浅层次        -name  filename  根据文件名字查找        -size  大小    根据文件大小进行查找            大小单位5

名字与地址转换getservbyname 与 getservbyport函数

名字与地址转换getservbyname 与 getservbyport函数 服务也通常靠名字来标志,getservbyname函数用于根据给定名字查找相应服务. #includestruct    servent *getservbyname( const char *servname, const char *protoname );成功:返回servent类型非空指针:失败:空指针:本函数返回非空指针 struct    servent{      char      *s_name;