c++ 友元(2)

一个类的成员函数作为另一个类的友元,该成员函数就必须在另一个类之前被声明。又因为类的成员函数必须在类内被声明,因此,两个类的顺序被固定。

Window_mgr类中的clear作为Screen的友元。遵循步骤:

        需要先定义Window_mgr类;

        声明clear函数,但不能定义,因为Screen还没有定义,不能使用Screen类。

        定义Screen类

        在类外定义clear。

typedef string::size_type screenindex;

class Window_mgr {
public:
	void clear(screenindex i);
private:
	vector<Screen> screens{ Screen(24,80,'a') };

};

class Screen {

	friend void Window_mgr::clear(screenindex i);
public:
	//pos
	typedef string::size_type pos;
	//构造函数
	Screen() = default;
	//接受高、宽、字符三个量来创建窗口。
	Screen(pos ht, pos wd, char c) :height(ht),width(wd),
		contents(ht*wd,c){}
	//接受高、宽两个参数来创建空白窗口
	Screen(pos ht, pos wd) :height(ht), width(wd),
	contents(ht*wd,' ') {}

	Screen& set(char);
	Screen& set(pos, pos, char);
	char get() const
	{
		return contents[cursor];
	}
	inline char get(pos ht, pos wd) const;
	Screen& move(pos r, pos c);
	Screen& display(ostream &os) {
	
		do_display(os); return *this;
	}
	const Screen& display(ostream& os) const {//后一个const说明了函数内部不改变成员变量,这是一个const成员函数
												//const对象只能调用const成员函数
		//前一个const 是因为后一个const将this变成一个指向const的cosnt指针。
		do_display(os); return *this;
	}
	
private:
	pos cursor = 0;
	pos height = 0, width = 0;
	string contents;

	void do_display(ostream& os) const { 
		for (pos i = 0; i < width * height; ++i) 
		{
			if (i % width == 0) cout << endl;
			cout << contents[i];
		
		} 
	}
};

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;
}

void Window_mgr::clear(screenindex i) {

	Screen& s = screens[i];
	s.contents = string(s.width*s.height,' ');
}

 

这样的定义使得clear成员函数变成Screen的友元,但是该代码的Window_mgr类中的成员vector screens定义是错误的,要先定义Screen类,才能将Screen作为vector的类型。

这样clear和screens就有冲突。将Window_mgr类整体设置为Screen的友元,冲突取消。

class Screen {

	friend class Window_mgr;

public:
	//pos
	typedef string::size_type pos;
	//构造函数
	Screen() = default;
	//接受高、宽、字符三个量来创建窗口。
	Screen(pos ht, pos wd, char c) :height(ht),width(wd),
		contents(ht*wd,c){}
	//接受高、宽两个参数来创建空白窗口
	Screen(pos ht, pos wd) :height(ht), width(wd),
	contents(ht*wd,' ') {}

	Screen& set(char);
	Screen& set(pos, pos, char);
	char get() const
	{
		return contents[cursor];
	}
	inline char get(pos ht, pos wd) const;
	Screen& move(pos r, pos c);
	Screen& display(ostream &os) {
	
		do_display(os); return *this;
	}
	const Screen& display(ostream& os) const {//后一个const说明了函数内部不改变成员变量,这是一个const成员函数
												//const对象只能调用const成员函数
		//前一个const 是因为后一个const将this变成一个指向const的cosnt指针。
		do_display(os); return *this;
	}
	
private:
	pos cursor = 0;
	pos height = 0, width = 0;
	string contents;

	void do_display(ostream& os) const { 
		for (pos i = 0; i < width * height; ++i) 
		{
			if (i % width == 0) cout << endl;
			cout << contents[i];
		
		} 
	}
};

class Window_mgr {
public:
	Window_mgr& clear(screenindex i);
	Window_mgr& print(screenindex i);
private:
	vector<Screen> screens{ Screen(24,80,'a') };

};

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;
}

Window_mgr& Window_mgr::clear(screenindex i) {

	Screen& s = screens[i];
	s.contents = string(s.width * s.height, ' ');
	return *this;
}
Window_mgr& Window_mgr::print(screenindex i) {
	Screen& s = screens[i];
	s.display(cout);
	return *this;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糖豆人鄭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值