7.3节练习

练习7.23 & 7.24 编写你的自己的Screen类。给你的Screen类添加三个构造函数:一个默认构造函数;另一个构造函数接受宽和高的值,然后将contents初始化成给定数量的空白;第三个构造函数接受宽和高的值以及一个字符,该字符作为初始化之后屏幕的内容。

#include <string>
class Screen
{
public:
	typedef std::string::size_type pos;
	Screen() = default;
	Screen(pos ht, pos wd) :height(ht), width(wd) {}
	Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd, c) {}

	char get()const { return contents[cursor]; }
	char get(pos ht, pos wd)const { pos row = ht*width; return contents[row + wd]; }
	Screen &move(pos, pos);
private:
	pos cursor = 0;
	pos height = 0;
	pos width = 0;
	std::string contents;
};
inline
Screen& Screen::move(pos r, pos c)
{
	pos row = r*width;
	cursor = row + c;
	return *this;
}

练习7.25 Screen能安全地依赖于拷贝和和赋值操作的默认版本吗?请说明理由。

不可以。

Screen myScreen(7, 77, 'n');//正确的一种初始化。n是char类型。
//错误,以下数据成员被定义为私有类型。
myScreen.width = 7;
myScreen.height = 77;
myScreen.cursor = 7777;
myScreen.contens = "nnnnnnnnnnnn";



练习7.26 将Sales_data::avg_price定义成内联函数。

三种将类成员函数定义成内联函数的方法。

1.隐式内联函数,定义在类内的成员函数。

2.显式内联函数,定义在类内的有inline标识符的成员函数。

3.显式内联函数,定义不在类内的成员函数,此时的inline是必须的。


练习7.27  给你自己的Screen类添加move、set、和display函数,通过执行下面的代码检验你的类是否正确。

#include <string>
class Screen
{
public:
	typedef std::string::size_type pos;
	Screen() = default;
	Screen(pos ht, pos wd) :height(ht), width(wd) {}
	Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd, c) {}

	char get()const { return contents[cursor]; }
	char get(pos ht, pos wd)const { pos row = ht*width; return contents[row + wd]; }
	Screen &move(pos, pos);
	Screen &set(char);
	Screen &set(pos, pos, 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;
	pos width = 0;
	std::string contents;
	void do_display(std::ostream &os) const { os << contents; }
};
Screen &Screen::set(char c)
{
	contents[cursor] = c;
	return *this;
}
Screen &Screen::set(pos r, pos c, char ch)
{
	contents[r*width + c] = ch;
	return *this;
}
inline
Screen& Screen::move(pos r, pos c)
{
	pos row = r*width;
	cursor = row + c;
	return *this;
}

练习7.28 如果move、set和display函数的返回类型不是Screen&而是Screen,则在上一个练习中将会发生什么情况。

如果返回类型不是对象的引用,而是对象的副本。

那么屏幕上第一行输出的是myScreen设置后的内容。

而第二行输出的是myScreen初始化的内容。


练习7.29 修改你的Screen类,令move、set和display函数返回screen并检查程序的运行结构,在上一个练习中你的推测正确吗?

。。。


练习7.30 通过this指针使用成员的做法虽然合法,但是有点多余。讨论显式地使用指针访问成员的优缺点。

(来源网上)

一般使用this指针都是类的成员函数,可以对类中的成员随意访问。

优点:this指针自动感应定位类成员。

缺点:使所有成员都用this看起来一致(有点牵强吧。。。)


练习7.31 定义一对类X和Y,其中X包含一个指向Y的指针,而Y包含一个类型为X的对象。

class X;
class Y;
class X {
	Y * ptr;
};
class Y {
	X item;
};


练习7.32 定义你自己的Screen和Window_mgr,其中clear是Window_mgr的成员,是Screende的友元。

#include <string>
#include <vector>
class Window_mgr
{
public:
	typedef std::string::size_type ScreenIndex;
	Window_mgr() = default;
	void clear(ScreenIndex);
private:
	std::vector<Screen> screens{ Screen{24,80,' '} };
};



class Screen
{
<pre name="code" class="cpp">	friend class Window_mgr;// 友元
public://...private://...};//成员函数的定义// 将celar()函数定义在Screen之后void Window_mgr::clear(ScreenIndex i){Screen &s = screens[i];s.contents = string(s.width*s.height, ' ');}

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值