练习7.27:
#include <iostream>
#include <cstring>
using namespace std;class Screen {private:unsigned height = 0, width = 0;unsigned cursor = 0;string contents;public:Screen() = default;Screen(unsigned ht, unsigned wd): height(ht), width(wd), contents(ht * wd, ' ') {}Screen(unsigned ht, unsigned wd, char c): height(ht), width(wd), contents(ht * wd, c) {}public:Screen &move(unsigned r, unsigned c) {cursor = r * width + c;return *this;}Screen &set(char ch) {contents[cursor] = ch;return *this;}Screen &set(unsigned r, unsigned c, char ch) {contents[r * width + c] = ch;return *this;}Screen &display() {cout << contents;return *this;}
};int main() {Screen myScreen(5, 5, 'X');myScreen.move(4, 0).set('#').display();cout << endl;myScreen.display();cout << endl;return 0;
}
测试结果:
练习7.28:
返回引用的函数是左值的,意味着这些函数返回的是对象本身而非对象的副本。如果我们把一系列这样的操作连接在一起的话,所有这些操作将在同一个对象上执行。
在上一个练习中,move、set和display函数的返回类型都是Screen&,表示我们首先移动光标至(4, 0)位置,然后将该位置的字符修改为’#’,最后输出myScreen的内容。
相反,如果我们把move、set和display函数的返回类型改成Screen,则上述函数各自只返回一个临时副本,不会改变myScreen的值。
练习7.29:
测试结果:
练习7.30:
通过this指针访问成员的优点是,可以非常明确地指出访问的是对象的成员,并且可以在成员函数中使用与数据成员同名的形参;缺点是显得多余,代码不够简洁。