类(三):类的作用域(学习笔记)

1.类的作用域

        类的作用域之外,普通的数据和函数成员只能由对象、引用或者指针访问运算符来访问。对于类类型成员,
    则使用作用域运算符来访问。 
     Screen::pos ht =24,wd = 80;
       Screen scr(ht,wd,'');
       Screen *p = &scr;
       char c = scr.get();                 //访问scr对象的get成员
       c = p->get();                       //访问p所指对象的get成员
   **作用域和定义在类外部的成员**
      class Window_mgr {
         public:
             // 窗口中每个屏幕的编号
             using ScreenIndex = std::vector <Screen>::size_type;
             //按照编号将指定的Screen重置为空白
             void clear(ScreenIndex);
          private:
              std::vector <Screen> screens{Screen(24,80,'')};
           };
           void Window_mgr::clear(ScreenIndex i)
           {
              //s是一个Screen的引用,指向我们想要清空的那个屏幕
              Screen &s =screen[i];
              //将那个选定的Screen重置空白
              s.contents = string(s.height *s.width,'');
           }
       如上所示程序,ScreenIndex和screen是在Window_mgr类中定义的。
       函数的返回类型通常出现在函数名之前。因此当成员函数定义在类的外部时,返回类型中使用的名字都位于
    类的作用域之外。这时,返回类型必须指明它是哪个类的成员。
     class Window_mgr {
           public:
           //向窗口添加一个Screen,返回它的编号
           ScreenIndex addScreen (const Screen&);
           };
      //首先处理返回类型,之后我们才进入Window_mgr的作用域
            Window_mgr::ScreenIndex
            Window_mgr::addScreen(const Screen &s)
            {
               screen.push_back(s);
               return screen.size()-1;
            }
      如上所示的例子中,要想使用ScreenIndex作为返回类型,我们必须明确指定哪个类定义了它。

      **名字查找** 

     名字查找是指寻找与所用名字最匹配的声明的过程。
**用于类成员声明的名字查找**
     声明中使用的名字,包括返回类型或者参数列表中使用的名字,都必须保证在使用前确保可见。如果某个成员的声明
 使用了类中尚未出现的名字,则编译器将会在定义该类的作用域中继续查找。
 **类型名要特殊处理**
     内层作用域可以重新定义外层作用域中的名字,即使该名字已经在内层作用域中使用过。然而在类中,如果成员使用
 了外层作用域中的某个名字,而该名字代表一种类型,则类不能在之后重新定义该名字:
    typedef double Money;
      class Account {
      public:
          Money balance() {return bal;}  //使用外层作用域的Money
      private:
          typedef double Money;          //错误:不能重新定义Money
          Money bal;
          };
  类型名的定义通常出现在类的开始处,这样就能确保所有使用该类型的成员都出现在类名的定义之后。

  **成员定义中的普通块作用域的名字查找**
  成员函数中使用的名字按照如下方式解析:
  (1)首先,在成员函数内查找该名字的声明。同理,只有在函数使用之前出现的声明才被考虑。
  (2)如果在成员函数内没有找到,则在类内继续查找,这时,类的所有成员都可以被考虑。
  (3)如果类内也没有找到该名字的声明,在成员函数定义之前的作用域内继续查找。
  尽管类的成员被隐藏了,但我们仍然可以通过加上类的名字或者显式地使用this指针来强制访问成员。

  **类作用域之后,在外围的作用域中查找**
  如果我们需要的是外层作用域中的名字,可以显式地通过作用域运算符(::)进行请求。

  **在文件中名字的出现处对其进行解析**
      当成员定义在类的外部时,名字查找的第三步不仅要考虑类定义之前的全局作用域中的声明,还需要考虑
  在成员函数定义之前的全局作用域中的声明。
    int height;     //定义了一个名字,稍后将在Screen中使用
      class Screen {
      public:
          typedef std::string::size_type ops;
          void setHeight(pos);
          pos height = 0;       //隐藏外层作用域中的height
          };

       Screen::pos verify(Screen::pos);
       void Screen::setHeight(pos var) {
       // var: 参数
       // height: 类的成员
       // verify: 全局函数
       height = verify(var);     //verify的声明位于setHeight的定义之前,因此可以被正常使用。
       }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值