`

c++ - c++ mutable members

    博客分类:
  • c++
c++ 
阅读更多

In the previeous post,     c++ special member functions- const and volatile members we have discussed some speical members, such as the constant members and the volatile members, now let's see a special members - which is called the mutable members. 

 

 

when we are talking about the mutable members,  we have to talk aobut the const members, when const object calls the const members, one constraint imposed by the const member classes is that they does not allow to modify the class members. such as 

 

 

const Screen cs(5, 5)

cs.move(3,4)
char ch = cs.get();

 

However, the move method does change the internal state of the object

 

 

inline void Screen::move(int r, int c) 
{
   if (checkRange(r, c) ) { 
    int row = (r - 1) * _width;
    _cursor = row + c - 1;
  }
}

 

you will end up in the compiler time error. 

 

to allow a class member to be modified even though it is the dat member of a const object. we can declare the data member as mutable.

 

 

such as 

 

 

	// from the above declaration below, to allow the move method to be called from a const object
	//string::size_type _cursor;
	mutable string::size_type _cursor;

 

 

below is the full declaration of the Screen class which you can try on your c++ code on the const and mutable classes.

 

#include <string>
#include <iostream>
#include <fstream>
#include <functional>
#include <iterator>
#include <algorithm>
#include <cstring>

using std::string;
using std::fstream;
using std::copy;
using std::cout;
using std::endl;
using std::cerr;
using std::strcpy;
using std::strcat;
using std::istream;
using std::ostream;

class Screen 
{
public:
	// constructor
	inline Screen(int hi = 8, int wid = 40, char bk = '*');


	void home() { _cursor = 0; } 
	void move(int, int); 

	void move(int , int ) const;
	char get() { return _screen[_cursor]; } 
	inline char get(int, int );
	bool checkRange(int, int) const;
	int height() { return _height;  } 
	int width() { return _width;} 

	// not defined, we might go to that later. 
	friend istream& operator >>(istream &, Screen &) ;
	friend ostream& operator <<(ostream&, const Screen &) ;

	void copy(const Screen & obj);

	inline void set(const string &s);
	inline void set(char s);

private:
	inline int remainingSpace();

	string _screen;
	// from the above declaration below, to allow the move method to be called from a const object
	//string::size_type _cursor;
	mutable string::size_type _cursor;
	int _height;
	int _width;


	/*static const int _height = 24;
	static const int _width =80;*/
};

void Screen::copy(const Screen &obj) 
{
	/// fif this Screen object and objs are the same objcet
	// no copy necessary 
	/// we look at hte 'this ' pointer 
	if (this != &obj) { 
		_height = obj._height;
		_width =obj._width;
		_cursor = 0;
		// create a new string 
		// its content is the same as obj._screen
		_screen = obj._screen;
	}
}


bool Screen::checkRange(int row, int col) const { 
	if (row < 1 || row > _height || 
		col < 1 || col > _width ) { 
			cerr << "Screen coordinates (" 
				<< row << ", " << col
				<< " ) out of bounds.\n";
			return false; 
	}
	return true;
	// a  better way is to write as such 
	//return !((row < 1 || row > _height || col < 1 || col > _width));
}

inline void Screen::move(int r,  int c) 
{
  // move _cursor to absolute position
	if (checkRange(r, c) ) { 
		int row = ( r - 1) * _width; // row location 
		_cursor = row + c - 1;
	}
}

inline void Screen::move(int r, int c) const 
{
	// can we directly call the Screen::move method or can we ask the Screen::move(int r, int c) to call the (Screen::move(int r, int c) const" method
	if (checkRange(r, c)) { 
		int row = (r - 1) * _width;
		_cursor = row + c - 1; // because now the _cursor is mutable members, it does not matter if you call it from a const contetxt
	}
}


// a side note, inline declaration should be placed 
// in the header file. normally you will carry the inline keyword with you . 
inline char Screen::get(int r, int c) {
	move(r, c);
	return get();
}

inline void Screen::set(const string &s) {
	// write string beginning at current _cursor position 
	int space = remainingSpace();
	int len = s.size();
	if (space < len) {
		cerr << "Screen: warning: truncate: " 
			<< "space: " << space 
			<< "string length: " << len << endl;
	}
}

inline void Screen::set(char ch) {
	if (ch == '\0') { 
		cerr << "Screen: Warning: " 
			<< "Null character (ignored).\n";
	} else { 
		_screen[_cursor] = ch;
	}
}
inline int Screen::remainingSpace() { 
	 // currrent position is no longer remaining
	int sz = _width * _height;
    return (sz - _cursor);
}


inline Screen::Screen(int hi, int wid, char bk) : 
    _height (hi),
	_width(wid),
	_cursor(0),
	_screen(hi * wid, bk) 
{
	// all the work is done with the number initialize list 
}

void test_screen1() 
{
	Screen sobj(3, 3); 
	string init("abcdefghi");

	cout << "Screen object )" 
		<< sobj.height() << " , "
		<< sobj.width() << " ) \n\n";

	// Set the content of hte screen 
	string::size_type initops = 0;
    
	for (int ix = 1; ix <= sobj.width(); ++ix) {
		for (int iy = 1; iy <= sobj.height(); ++iy) {
			sobj.move(ix, iy);
			sobj.set(init[initops++]);
		}
	}

	// print the conent of the screen
	for (int ix = 1; ix <= sobj.width(); ++ix) {
		for (int iy = 1; iy <= sobj.height(); ++iy) { 
			cout << sobj.get(ix, iy);
		}
		cout << "\n";
	}

}

void test_const_mutable()
{
	const Screen cs(5, 5);

	// however, now you cannot call the move method, because the move method change the _cursor 
	// to make that happen, you have to change the type of the _cursor
	// from
	//     string::size_type _cursor;
	//
	// to 
	//     mutable string::size_type _cursor;
	cs.move(3, 4);

}
 

 

分享到:
评论

相关推荐

    Laravel开发-eloquence-mutable

    Laravel开发-eloquence-mutable 灵活的可搜索、可映射、元表、验证和更广泛的扩展,适用于大型雄辩ORM。

    mutable-dev-environment:Mutable Instruments产品固件的开发环境

    易变的环境,适用于Mutable Instruments模块黑客 该配置文件和此shellscript创建了一个Linux(ubuntu)虚拟机,该虚拟机配置有用于编译和安装Mutable Instruments模块的固件的所有正确工具。 荣誉和灵感 Adafruit的 ...

    ambika-case:Mutable Instruments Ambika的案例和面板文件

    Mutable Instruments Ambika的案例和面板文件 笔记: 已将Panel SVG文件设置为在svg2shenzhen扩展名的Inkscape中使用,以导出Gerber。 机箱+脸颊文件有两种类型,具体取决于在顶面板和主板之间使用的长度支架。 ...

    shruthi-xt-enclosure:Mutable Instruments Shruthi XT单合成器的木质外壳的计划和零件

    Shruthi XT机箱 我的木制Shruthi XT外壳的设计和零件,可以选择在激光上雕刻有灵感源自原始设计的图形。 零件设计为在CNC铣床上粗切,然后手工精加工和修整。档案文件该计划最初是使用Mac版Eazydraw绘制的。...

    teensy-braids:Mutable Instruments Braids的端口连接到Teensy板

    青少年辫子Mutable Instruments Braids的端口连接到Teensy板该项目提取Mutable Instruments Braids宏振荡器,并使用teensy的模拟输出(引脚A14)作为音频输出。 闪烁后,Teensy会接收MIDI-USB消息。 振荡器连续发出...

    C++中volatile和mutable关键字用法详解

    主要介绍了C++中volatile和mutable关键字用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    聊聊C++的mutable和volatile

    C++中修饰数据可变的关键字有三个:const、volatile和mutable。const比较好理解,表示其修饰的内容不可改变(至少编译期不可改变),而volatile和mutable恰好相反,指示数据总是可变的。mutable和volatile均可以和...

    详解C++中mutable的用法

    主要介绍了详解C++中mutable的用法,帮助大家更好的理解和学习C++,感兴趣的朋友可以了解下

    Practical C++ Programming C++编程实践

    : Construct The Comma Operator Overloading the ( ) Operator Pointers to Members The asm Statement The mutable Qualifier Run Time Type Identification Trigraphs Answers to Chapter Questions 30....

    深入解析C++中的mutable关键字

    在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中

    深入理解C++中的mutable关键字

     在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。  我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成...

    浅谈C++中的mutable和volatile关键字

    在C++中,mutable是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被修改。mutable在类中只能够修饰非...

    C++从零开始---入门教程

    C++从零开始(十七)——C++中的一些生僻关键字(explicit、mutable、volatile等的说 明) C++从零开始(十八)——何谓SDK(说明为什么没有放音乐的指令却依然可以编出 放音乐的程序) C++从零开始(十九)——何谓...

    c++关键字mutable深入解析

    先说用法,mutable关键字只能修饰非静态以及非常量成员变量,使用mutable修饰的成员变量在const函数中的值是可以修改的

    C++中mutable与volatile的深入理解

    C++中修饰数据可变的关键字有三个:const、volatile和mutable。const比较好理解,表示其修饰的内容不可改变(至少编译期不可改变),而volatile和mutable恰好相反,指示数据总是可变的。mutable和volatile均可以和...

    ANSI C++特征总结

    这些新特征包括关键字 mutable 以及explicit。 有一些修改的潜在作用很大。现在 ANSI 规则鼓励某些编程方法而抛弃其他一些编程方 法。尽管在一段时间内不会放弃对老式编程方法的支持,但是有一些编程方法最终是要...

    More Effective C++中文版

    一些经过验证的用来改善程序效率的方法,包括检验C++... 介绍新的语言特性,包括bool、mutable、explicit、namespaces、成员模板、标准模板库等。如果你的编译器不支持这些特性,本书还介绍了如何不利用它们完成工作。

    LeetCode最全代码

    201 | [Bitwise AND of Numbers Range](https://leetcode.com/problems/bitwise-and-of-numbers-range/) | [C++](./C++/bitwise-and-of-numbers-range.cpp) [Python](./Python/bitwise-and-of-numbers-range.py) | _...

Global site tag (gtag.js) - Google Analytics