类的作用域
在类的作用域之外,普通的数据和函数成员只能由对象、引用或者指针使用成员访问运算符来访问
Screen::pos ht = 3, wd = 3; // 使用Screen定义的pos类型
Screen scr(ht, wd, 'X');
Screen *p = &scr;
char c = scr.get(); // 类对象调用成员函数
p->display(cout); // 类指针调用成员函数
如果返回类型是类里面定义的类型,也需要加上类名和作用域解析运算符
class Window_mgr {
public:
ScreenIndex addScreen(const Screen&);
};
Window_mgr::ScreenIndex
Window_mgr::addScreen(const Screen& s) {
screens.push_back(s);
return screens.size() - 1;
}
7.4.1 名字查找与类的作用域
编译器处理完类中的全部声明后才会处理成员函数的定义
成员函数中使用的名字按照如下方式解析:
- 首先,在成员函数内查找该名字的声明
- 如果在成员函数内没有找到,则在类内继续查找,这时类的所有成员都可以被考虑
- 如果类内也没有该名字的声明,就在成员函数定义之前的作用域内继续查找
int height; // 定义一个全局名字,待会在Screen中使用
class Screen {
public:
typedef string::size_type pos;
void dummy_fcn(pos height) {
cursor = width * height; // 使用的是参数声明
}
private:
pos cursor = 0;
pos height = 0, width = 0;
};
如果硬要使用类的成员,可以显式地用this
或类名
void dummy_fcn(pos height) {
cursor = width * this->height; // 使用的是类的成员
// cursor = width * Screen::hegiht;
}
如果要用到外层作用域中的名字,可以显式地通过作用域运算符来请求
void dummy_fcn(pos height) {
cursor = width * ::height; // 使用的是全局变量
}
成员函数定义在类的外部时,名字查找不仅要考虑类定义之前的全局作用域中的声明,还要考虑成员函数定义之前的全局作用域中的声明
int height;
class Screen {
public:
typedef string::size_type pos;
void setHeight(pos);
pos height = 0;
};
Screen::pos verity(Screen::pos); // 全局函数的声明
void Screen::setHeight(pos var) {
height = verify(var);
}
这里成员函数setHeight
用到的verify
全局函数,已经在成员函数定义之前声明了,所以可以正常使用,height
已经在类里面声明了,所以成员函数里面的height
就是类的成员了