欢迎光临散文网 会员登陆 & 注册

C++ 类的作用域

2023-04-15 15:12 作者:S-a-i_  | 我要投稿

在类的作用域之外,普通的数据和函数成员只能由对象、引用或者指针使用成员访问运算符访问,对于类类型成员,则使用作用域访问运算符。

作用域和定在类外部的成员

例如我们定义Window_mgr类的clear成员

因为编译器在参数列表之前已经明确了我们当前正位于Window_mgr类的作用域之中,所以不必再专门说明ScreenIndex是Window_mgr类定义的,screens同理。

另一方面,函数的返回类型通常出现在函数名之前,因此当成员函数定义在类的外部时,返回类型中使用的名字都位于作用域之外,这是返回类型必须指明他是哪个类的成员

例如:


名字查找与类的作用域

在我们编写的程序中名字查找的过程比较直截了当

1在名字所在的块中寻找其声明语句,只考虑在名字使用之前出现的声明

2如果没找到继续查找外层作用域

3如果最终没有找到声明,报错

对于定义在类中的成员函数来说,解析其中名字的方式和上面有区别

1编译成员声明

2直到类全部可见后才编译函数体


用于类成员声明的名字查找

这种两阶段的处理方式只适用于成员函数中使用的名字,声明中使用的名字包括返回类型或参数列表中使用的名字,都必须在使用前确保可见,如果某个成员的声明使用了类中没有出现的名字,则编译器将会在定义该类的作用域中继续查找。

当编译器看到balance的声明时,他将在Account类中查找对Money的声明,编译器只考虑Account中使用Money前出现的声明,因为没有找到匹配,所以编译器会接着到Account的外层作用域中查找。这个例子中,编译器会找到Money的typedef语句,该类型被用作balance函数的返回类型,以及数据成员bal的类型,另一方面因为balance函数只有在整个类可见后才被处理,所以return返回的是名为bal的成员不是string对象。


类型名要特殊处理

一般来说内层作用域可以重定义外层作用域中的名字,即使该名字已经在内层使用过,然而在类中,如果成员使用了外层作用域的某个名字,而该名字代表一种类型,则类不能再之后重新定义该名字。

即使Account中定义的Money类型和外层一致,上述代码依旧是错误的。

注意:重新定义类型名字是一种错误的行为,但是编译器并不为此负责,一些编译器还是可以通过这样的代码。

注意:类型名的定义通常出现在类的开始处,这样就能确保所有使用该类型的成员都出现在定义之后。


成员定义的普通块作用域的名字查找

解析成员函数中使用的名字

1在成员函数内查找该名字的声明,只有在函数使用之前出现的声明才被考虑

2如果在成员函数内没有找到,则在类内继续查找,这时类的所有成员都可以被考虑。

3如果类内没有找到声明,在成员函数定义之前的作用域内继续查找


一般来说不要使用成员的名字作为某个成员函数的参数!

处理cursor时,他首先在函数作用域内查找表达式中用到的名字,函数的参数位于作用域中,因此用到的height使用的是参数height。

例子中,height参数隐藏了同名的成员

并不建议使用上述代码,如果参数使用其他名字是最好的方法。另一方面即使成员函数内隐藏了成员height但是我们可以强行访问它。


类作用域之后,在外围的作用域中查找

如果我们需要外层作用域的height


在文件中名字的出现对其进行解析

成员定义在类的外部时,名字查找的第三步不仅要考虑类定义之前的全局作用域中的声明,还要考虑在成员函数定义之前的全局作用域中的声明。

verify的声明在Screen类的定义之前是不可见的,然而名字查找的第三步包括了成员函数出现之前的全局作用域,因为verify的声明位于setHeight的定义之前,所以可以被正常使用。

C++ 类的作用域的评论 (共 条)

分享到微博请遵守国家法律