C++常量对象,常成员函数

#include <stdio.h>
#include<iostream>
#include <string.h>
#include <stdlib.h>
#include<string>
#include<vector>
using namespace std;

//
class Screen {
public:
	typedef string::size_type pos; //专门用来定义类型 的成员必须先定义后使用他
	/*
	screen 的用户不会知道screen内部使用了一个string对象来存放他的数据,
	通过把pos定义成public成员可以隐藏screen的实现细节
	*/
	Screen() = default;
	Screen(int a,int b){}
	Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd, c){ }

	char get() const {  //隐式的内联,const写到后面,这是个常成员函数
		/*
		常成员函数意义:不改变对象的成员变量的值,与普通的成员函数改变变量值形成对比
		*/
		//height = 1; //编译报错,常成员函数不可以修改成员变量的值哦!
		return contents[cursor];
	}
	inline char get(pos ht, pos wd)const; //显式的内联,也是常成员函数
	Screen &move(pos r, pos c);  //能在之后类的外部被设为内联
	const Screen&  display(ostream &os);  //const成员,返回const 型的Screen对象 ,即,常量对象,常量对象的成员一般是不能修改的
	Screen& display_2(ostream&os) {
		do_display(os);
		return *this;
		}
	const Screen &display(ostream&os) const{
		do_display(os);
		return *this;
	}

private:
	pos cursor = 0;
	pos height = 0, width = 0;
	string contents;
	void do_display(ostream&os)const {
		os << contents;
	}
public:
	//可变数据成员
		/*
		有时候希望改变类的某个数据成员,即使他是在一个const成员函数里面
		  那么可以通过在变量的声明中加入mutable关键字做到
		  一个可变数据成员(mutable data member)永远不会是const,即使他是const对象的成员
		  */
	void some_member() const;  // 声明一个常类成员函数,那么他就不能修改类的成员数据,除非是mutable
private:
	
	mutable size_t access_ctr;// 既使一个在const对象内也能被修改
public: //很一般的成员函数
	Screen& set(char);
	Screen &set(pos, pos, char);
};
//令move成员作为内联函数
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];
}


//返回*this的成员函数
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;
}
//const成员函数,而且返回引用
inline const Screen& Screen::display(ostream&a) {
	//height = 1;//因为不是常成员函数,所以可以修改成员变量
	//一个const成员函数如果以引用的形式返回*this,那么他的返回类型是常量引用
	//++access_ctr;//因为是mutable类型,所以可以修改哦

	return *this;
}

//重载成员函数
Screen myscreen;
char ch = myscreen.get(); //调用Screen::get()
char ch2 = myscreen.get(0, 0); //调用Screen::get(0,0)

void Screen::some_member() const{
// 这里你换成了height成员数据,那他就报错说不能修改
	++access_ctr;//保存一个计数值,用于记录成员函数被调用的次数
	
 }

class window_mgr {
private:
//这个window_mgr追踪的Screen
//默认情况下,一个window_mgr包含一个标准尺度的空白Screen
	vector<Screen> screens{ Screen(24,80, ' ') };//容器screens包含一个Screen对象

 };
/*
当我们初始化 类类型 的成员时,需要为构造函数传递一个符合成员类型的实参数

*/



int main() {
	cout << "7.3 类的其他属性";
	Screen myScreen; //非常量的对象
	//display是一个返回常量引用,调用set会引发错误
	//myScreen.display(cout).set('a');//报错!!常量引用调用非常量的成员函数,那么这个成员函数很有可能修改被调用对象的成员数据,而这与const矛盾
	myScreen.display(cout).get();//返回常量对象的引用,这个常量引用调用常成员函数是OK的
	myscreen.move(4, 0).set('a');
	const Screen blank(5, 3);
	blank.display(cout);//常量对象调用常成员,
	//blank.display_2(cout);报错
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值