zoukankan      html  css  js  c++  java
  • C++ 类的作用域

    访问成员

    每个类都会定义它自己的作用域。在类的作用域之外,普通的数据和函数成员只能由对象、引用或者指针使用成员访问运算符来访问。对于类类型成员则使用作用域运算符访问

        Screen::pos row = 3;
        Screen::pos col = 4;
        Screen screen(row, col, 'c');
        screen.get();
        Screen *psc = &screen;
        psc->get();
    

    类的外部定义成员函数时必须同时提供类名和函数名。在类的内部定义的成员函数不需要提供类名,成员函数内部调用类定义的变量和类型,无需提供类名。举个例子

    void Window_mgr::clear(ScreenIndex i)
    {
        // s是一个Screen的引用,指向我们想清空的屏幕
        Screen &s = screens[i];
        //清空屏幕
        s.contents = string(s.height * s.width, ' ');
    }
    

    这是我们之前实现的clear, ScreenIndex为类内定义的类型,所以无需加Window_mgr::
    反之,如果我们在类外定义一个新的函数addScreen函数,其返回值为ScreenIndex类型,就需要添加Window_mgr::

    class Window_mgr
    {
    public:
        //窗口中每个屏幕的编号
        using ScreenIndex = std::vector<Screen>::size_type;
        //按照编号将指定的Screen重置为空白
        void clear(ScreenIndex);
        ScreenIndex addScreen(const Screen &);
    
    private:
        std::vector<Screen> screens{Screen(24, 80, ' ')};
    };
    

    这里要注意所有用到ScreenIndex类型的函数,一定要在 using ScreenIndex 类型声明的下边,否则编译器会报错,因为编译器检测函数声明类型是按顺序的。接下来如果在类外实现addScreen,就要为ScreenIndex添加Window_mgr类名

    Window_mgr::ScreenIndex Window_mgr::addScreen(const Screen &s)
    {
        screens.push_back(s);
        return screens.size() - 1;
    }
    

    变量查找和作用域

    类的定义分两步处理:
    · 首先,编译成员的声明。
    · 直到类全部可见后才编译函数体。
    编译器处理完类中的全部声明后才会处理成员函数的定义。
    所以我们可以在类中定义的函数使用类的任何成员变量而不会报错

     //读取光标处字符
        char get() const
        {
            //隐式内联
            return contents[cursor];
        }
    

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

    typedef double Money;
    class Account
    {
    public:
        Money balance() { return bal; }
    
    private:
        Money bal;
    };
    

    当编译器看到balance函数的声明语句时,它将在Account类的范围内寻找对Money的声明。编译器只考虑Account中在使用Money前出现的声明,因为没找到匹配的成员,所以编译器会接着到Account的外层作用域中查找。在这个例子中,编译器会找到Money的typedef语句,该类型被用作balance函数的返回类型以及数据成员bal的类型.

    成员函数中变量查找规则

    成员函数中使用的名字按照如下方式解析:
    · 首先,在成员函数内查找该名字的声明。和前面一样,只有在函数使用之前出现的声明才被考虑。
    · 如果在成员函数内没有找到,则在类内继续查找,这时类的所有成员都可以被考虑。
    · 如果类内也没找到该名字的声明,在成员函数定义之前的作用域内继续查找。
    如果全局作用域定义了一个变量名和成员函数内使用的变量名一样,则优先查找类中是否有同名的成员名,如果有使用的就是类的成员变量。
    如果成员函数的形参名和成员变量名相同,则会覆盖同名的成员变量,可以使用this指代成员变量避免错误

      void setbalance(Money bal)
        {
            this->bal = bal;
        }
    

    源码链接https://gitee.com/secondtonone1/cpplearn
    我的公众号,谢谢关注
    https://cdn.llfc.club/gzh.jpg

    重剑无锋,大巧不工
  • 相关阅读:
    AvalonDock使用体验
    使用vs2015时,拖拉窗口,窗口隐藏后点击显示就会报错,错误代码“已在“VisualTreeChanged”事件期间更改可视化树”。
    es6的常用新特性
    js如何准确获取当前页面url网址信息
    移动端1px细线解决方案总结
    Zepto tap 穿透bug、解决移动端点击穿透问题
    js继承的方式有几种
    js常用的几种模式
    判断对象类型 typeof instanceof Object.prototype.tostring()
    new的实现机制
  • 原文地址:https://www.cnblogs.com/secondtonone1/p/15740146.html
Copyright © 2011-2022 走看看