C++ primer 第七章 Screen类和Windows_mgr类实现 一体式笔记(含大量注释)

Screen类实现:

#pragma once
#include<string>
#include<iostream>

class Screen {
	friend class Windows_mgr;//类也可以被定义为友元

public:
	//用于定义类型的成员必须先定义后使用
	typedef std::string::size_type pos;	//string::size_type类型与unsigned具有相同含义,其长度与实际机器适配,是string类定义的配套类型,例如size()的返回类型就是size_type类型
	//using pos = std::string::size_type;	别名声明,与typedef等价

	/*构造函数*/
	explicit	//阻止了隐式通过该构造函数创建对象
	Screen(pos ht,pos wd,char c):height(ht),width(wd),	//最好初始值顺序与声明保持一致,也尽量避免使用某些成员初始化其他成员
		contents(ht * wd, c) {	}	//cursor被类内初始值初始化为0
	Screen(): Screen(0, 0, ' ') { }	//委托构造函数,使用所属类其他构造函数执行自己的初始化过程

	/*类内成员函数*/
	//获取位置和移动
	char get() const	//隐式内联
		{ return contents[cursor]; }	//读取光标处字符
	inline char get(pos ht, pos wd) const;	//显式内联
	Screen& move(pos r, pos c);		//定义时设为内联

	//设置光标位置
	Screen& set(char);	//返回*this的成员函数,于是我们就可以这样用:myScreen.move(4,0).set('#')
	Screen& set(pos, pos, char);	//上面表达正确是由于我们返回的是myScreen的别名,而不是副本

	//display方法
	//一个const成员函数如果以引用的形式返回*this,那么它的返回类型将是常量引用
	Screen &display(std::ostream &os)
		{ do_display(os); return *this; }	//于是我们可以使用myScreen.display(cout).set('*'),并且负责打印的函数是const函数
	const Screen& display(std::ostream& os) const
		{ do_display(os); return *this; }

	Screen& clear(char = bkground);	//使用静态成员作为静态实参

private:
	pos cursor = 0;
	pos height = 0, width = 0;
	std::string contents;

	//静态成员
	static const char bkground;

	/*类内成员函数*/
	void do_display(std::ostream& os) const { os << contents; }	//是内联函数,不会产生额外开销,同时又保证了设计的优良性
};

/*类外定义成员函数*/
inline	//能在外部用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;
}

Windows_mgr类实现:

#pragma once
#include"Screen.h"
#include<vector>

/*令某个成员函数作为友元,设计程序流程如下:
* 1、首先定义Window_mgr类,其中声明clear函数,但是不能定义它;
*    在使用Screen的成员前必须先声明Screen;
* 2、接下来定义Screen,包括对于clear的友元声明
* 3、最后定义clear,此时它才可以使用Screen的成员
*/

class Windows_mgr {

public:
	using ScreenIndex = std::vector<Screen>::size_type;	//vector定义的size_type类型与string一致,unsigned,注意:作用域只在类内
	//按照编号将特定Screen重置为空白
	void clear(ScreenIndex);

	//向窗口添加一个Screen,返回编号
	ScreenIndex addScreen(const Screen&);

private:
	//这个Windows_mgr追踪的Screen
	//默认情况下。一个Window_mgr包含一个标准尺寸的空白Screen
	std::vector<Screen> screens{ Screen(24,80,' ') };//当提供一个类内初始值是,必须以符号=或者花括号表示

};
void Windows_mgr::clear(ScreenIndex i) {
	Screen& s = screens[i];
	s.contents = std::string(s.height * s.width, ' ');
}
Windows_mgr::ScreenIndex	//返回类型出现在函数名之前,其定义在类的作用域内,使用在作用域之外,所以必须指明是哪个类定义了它
Windows_mgr::addScreen(const Screen& s) {
	screens.push_back(s);	//vector容器的动态长度
	return screens.size() - 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值