7.23
#ifndef SCREEN_H
#define SCREEN_H
class Screen {
public:
using pos = std::string::size_type;
Screen() = default;
Screen(pos ht, pos wd): height(ht), width(wd), contents(ht * wd, ' ') { }
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);
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
};
char Screen::get(pos r, pos c) const
{
return contents[r * width + c];
}
inline Screen &move(pos r, pos c)
{
cursor = r * width + c;
return *this;
}
#endif
7.24 见7.23代码
7.25 可以使用默认版本,其数据成员cursor,height和width都是内置类型,contents是string类型,定义了拷贝和赋值运算符,默认版本能够正确处理。
7.26
class Sales_data {
public:
/* ... */
double avg_price() const;
/* ... */
};
inline double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
7.27 Screen类:
#ifndef SCREEN_H
#define SCREEN_H
class Screen {
public:
using pos = std::string::size_type;
Screen() = default;
Screen(pos ht, pos wd): height(ht), width(wd), contents(ht * wd, ' ') { }
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);
Screen &set(char);
Screen &display(std::ostream &os) { do_display(os); return *this; }
const Screen &display(std::ostream &os) const { do_display(os); return *this; }
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
void do_display(std::ostream &os) const { os << contents; }
};
char Screen::get(pos r, pos c) const
{
return contents[r * width + c];
}
inline Screen &Screen::move(pos r, pos c)
{
cursor = r * width + c;
return *this;
}
inline Screen &Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
#endif
测试程序:
#include <iostream>
#include "Screen.h"
using namespace std;
int main()
{
Screen myScreen(5, 5, 'X');
myScreen.move(4, 0).set('#').display(cout);
cout << '\n';
myScreen.display(cout);
cout << "\n";
return 0;
}
7.28 返回类型为Screen,只会返回对象的副本,不会改变对象的值。
7.29 改为Screen,myScreen值不变。
7.30 优点是比较明确,缺点是不够简洁。
7.31
class Y;
class X {
private:
Y *py;
};
class Y {
private:
X x0;
}
7.32
#ifndef SCREEN_H
#define SCREEN_H
#include <vector>
using std::string;
using std::vector;
class Screen;
class Window_mgr {
public:
using ScreenIndex = std::vector<Screen>::size_type;
void clear(ScreenIndex);
private:
vector<Screen> screens;
};
class Screen {
friend void Window_mgr::clear(Window_mgr::ScreenIndex);
public:
using pos = std::string::size_type;
Screen() = default;
Screen(pos ht, pos wd): height(ht), width(wd), contents(ht * wd, ' ') { }
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);
Screen &set(char);
Screen &display(std::ostream &os) { do_display(os); return *this; }
const Screen &display(std::ostream &os) const { do_display(os); return *this; }
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
void do_display(std::ostream &os) const { os << contents; }
};
char Screen::get(pos r, pos c) const
{
return contents[r * width + c];
}
inline Screen &Screen::move(pos r, pos c)
{
cursor = r * width + c;
return *this;
}
inline Screen &Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
void Window_mgr::clear(ScreenIndex i)
{
Screen &s = screens[i];
s.contents = string(s.height * s.width, ' ');
}
#endif
本文详细讨论了C++ Primer第五版第7.3.1到7.3.4节的练习,涉及Screen类的相关操作,包括默认拷贝构造函数的适用性、对象副本的返回、成员变量的影响以及代码的优缺点分析。
353

被折叠的 条评论
为什么被折叠?



