这篇接着First Part通过构造Screen和Window_mgr介绍类的其他特性. 首先介绍要构造的Screen和Window_mgr这两个类:
Screen表示显示器的一个窗口类型成员包括: 代表string::size_type类型的pos成员数据成员包括: string类型的contents成员, 存储显示的内容.三个string::size_type类型的cursor height width成员, 分别表示光标位置, 屏幕的高和宽.可变数据成员包括: size_t类型的access_ctr成员, 表示每个Screen成员函数被调用的次数.成员函数包括:
get函数, 读取给定位置字符.set函数, 设置给定位置字符.display函数, 打印Screen的内容.move函数, 移动光标.Window_mgr表示管理窗口的类
数据成员包括: Screen vector类型的screens成员, 表示一个屏幕的窗口组.size_type类型的ScreenIndex成员, 表示屏幕中每个窗口的编号.成员函数包括: clear函数, 清除屏幕中指定编号的窗口. class Screen { friend class Window_mgr; // 类间友元声明 // friend void Window_mgr::clear(ScreenIndex); public: typedef std::string::size_type pos; // 类型成员 private: pos cursor = 0; pos height = 0, width = 0; std::string contents; mutable size_t access_ctr; // 可变数据成员 public: Screen() = default; Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) {} // 成员函数重载 char get() const{ return contents[cursor]; } inline char get(pos r, pos c) const; Screen &move(pos r, pos c); // 基于const的重载 Screen &display(std::ostream &os) { do_display(os); return *this; } const Screen &display(std::ostream &os) const { do_display(os); return *this; } private: void do_display(std::ostream &os) const { os << contents; } } inline Screen &Screen::move(pos r, pos c) { pos row = r * width; cursor = row + c; return *this; } char Screen::get(pos r, pos c) const { pos row = r * width; return contents[row + c]; } inline Screen &Screen::set(char c) { contents[cursor] = c; return *this; } inline Screen &Screen::set(pos r, pos col, char ch) { contents[r * width + col] = ch; return *this; } class Window_mgr { public: using ScreenIndex = std::vector<Screen>::size_type; // 窗口中每个屏幕的编号 void clear(ScreenIndex); // 清除屏幕 ScreenIndex addscreen(const Screen&); private: std::vector<Screen> screens{Screen(24, 80, ' ')}; // 窗口中的屏幕 } void Window_mgr::clear(ScreenIndex i) { Screen &s = screens[i]; s.contents = string(s.height * s.width, ' '); // 访问了Screen的私有成员 } Window_mgr::ScreenIndex Window_mgr::addscreen(const Screen &s) { screens.push_back(s); return screens.size() - 1; } 类型成员 一个类不仅可以有数据成员和成员函数, 还可以包含类型成员. 类型成员实际上就是在类内部定义的类型别名, 使用类型成员的目的在于隐藏数据成员的类型. 以下两条语句都可以定义类型成员: typedef std::string::size_type pos; using pos = std::string::size_type注意: 1. 类型成员受访问限制符的限制 2. 类型成员必须先定义后使用, 建议将类型成员定义至于类首
注意: inline函数应该与相应的类定义在同一个头文件中
委托构造函数的执行顺序是: 接受委托的构造函数的初始化列表->接受委托的构造函数的函数体->委托函数的函数体 .