Если класс будет интенсивно использоваться,
error: cannot modify a data member within a const member function
ошибка: не могу модифицировать данные-члены внутри константной функции-члена
Если класс будет интенсивно использоваться, лучше объявить его функции-члены, не модифицирующие данных, константными. Однако наличие спецификатора const в объявлении функции-члена не предотвращает все возможные изменения. Такое объявление гарантирует лишь, что функции-члены не смогут изменять данные-члены, но если класс содержит указатели, то адресуемые ими объекты могут быть модифицированы константной функцией, не вызывая ошибки компиляции. Это часто приводит в недоумение начинающих программистов. Например:
#include <cstring>
class Text {
public:
void bad( const string &parm ) const;
private:
char *_text;
};
void Text::bad( const string &parm ) const
{
_text = parm.c_str(); // ошибка: нельзя модифицировать _text
for ( int ix = 0; ix < parm.size(); ++ix )
_text[ix] = parm[ix]; // плохой стиль, но не ошибка
}
Модифицировать _text нельзя, но это объект типа char*, и символы, на которые он указывает, можно изменить внутри константной функции-члена класса Text. Функция-член bad() демонстрирует плохой стиль программирования. Константность функции-члена не гарантирует, что объекты внутри класса останутся неизменными после ее вызова, причем компилятор не поможет обнаружить такую ситуацию.
Константную функцию-член можно перегружать неконстантной функцией с тем же списком параметров:
class Screen {
public:
char get(int x, int y);
char get(int x, int y) const;
// ...
};
В этом случае наличие спецификатора const у объекта класса определяет, какая из двух функций будет вызвана:
int main() {
const Screen cs;
Screen s;
char ch = cs.get(0,0); // вызывает константную функцию-член
ch = s.get(0,0); // вызывает неконстантную функцию-член
}
Хотя конструкторы и деструкторы не являются константными функциями-членами, они все же могут вызываться для константных объектов. Объект становится константным после того, как конструктор проинициализирует его, и перестает быть таковым, как только вызывается деструктор. Таким образом, объект со спецификатором const трактуется как константный с момента завершения работы конструктора и до вызова деструктора.
Функцию-член можно также объявить со спецификатором volatile (он был введен в разделе 3.13). Объект класса объявляется как volatile, если его значение изменяется способом, который не обнаруживается компилятором (например, если это структура данных, представляющая порт ввода/вывода). Для таких объектов вызываются только функции-члены с тем же спецификатором, конструкторы и деструкторы:
class Screen {
public:
char poll() volatile;
// ...
};
char Screen::poll() volatile { ... }
Содержание Назад Вперед