|
当我们把一个Screen 类对象声明为const 时出现了一些问题,我们期望的行为是一旦 const Screen 对象被初始化,它的内容就不能被修改但是我们应该能够监视到Screen 对象 的内容,例如给出下面的Screen 对象cs const Screen cs( 5, 5 ); 我们想监视在位置(3, 4)的内容我们这样做 // 读位置(3, 4)的内容 // 喔! 不能工作 cs.move( 3, 4 ); char ch = cs.get(); 但是这不能工作你知道为什么吗?move()不是const 成员函数,而且不能很容易地 变成const 成员函数,move()的定义如下 inline void Screen::move( int r, int c ) { if ( checkRange( r, c ) ) { int row = (r-1) * _width; _cursor = row + c - 1; // 修改 _cursor } } 我们注意到move()修改了数据成员_cursor ,因此若不加改动它就不能被声明为const. 但是对一个Screen 类的const 对象不能修改_cursor ,这看起来可能很奇怪,因为_cursor 只是一个索引,修改_cursor 不会修改Screen 本身的内容.我们只是想记住要被监视的Screen 位置,即使Screen 对象是const 也应该允许修改_cursor, 因为这么做对于监视Screen 对象 的内容是必需的而且又不会修改Screen 本身的内容. 为了允许修改一个类的数据成员,即使它是一个const 对象的数据成员,我们也可以把 该数据成员声明为mutable(易变的),mutable 数据成员永远不会是const 成员,即使它是 一个const 对象的数据成员.mutable 成员总可以被更新,即使是在一个const 成员函数中. 为把一个成员声明为mutable 数据成员,我们必须把关键字mutable 放在类成员表中的数据成 员声明之前 class Screen { public: // 成员函数 private: string _screen; mutable string::size_type _cursor; // mutable 成员 short _height; short _width; }; 现在任何const成员函数都可以修改_cursor,我们可以把成员函数move()声明为const; 即使move()修改了数据成员_cursor 也不会有编译错误产生 // move() 是一个 const 成员函数 inline void Screen::move( int r, int c ) const { // ... // ok: const 成员函数可以修改 mutable 成员 _cursor = row + c - 1; // ... } 现在我们可以执行本小节开始时给出的操作来监视Screen 对象cs ,而不会有错误发生. 我们注意到只有_cursor 被声明为mutable 数据成员,而_screen _height 和_width 都没有, 因为这些数据成员的值在const 的Screen 类对象中是不应该被改变的。
|
一共有 0 条评论