玩命加载中 . . .

7.4-类的作用域


类的作用域

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

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就是类的成员了


文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录