Изменяемая переменная изменена неконстантной функцией-членом

Я изучаю C ++, и я прочитал это: Если элемент данных объявляется изменяемым, то можно присвоить значение этому элементу данных из функции-члена const.
Но следующий код скомпилирован без каких-либо ошибок или предупреждений от gcc.
(Это не реальный пример кода, я просто написал его, чтобы проверить ключевое слово mutable)

class M
{
public:
M(){x=10;};
int getX() {x++; return x;};
private:
mutable int x;
};

int main()
{
M xx;
std::cout << xx.getX() << std::endl;
}

Разве я не должен объявлять getX как const?

Правка 1 (ответ ForEver проясняет ситуацию), следующий код не будет скомпилирован:

class M
{
public:
M(){x=10;};
int getX() const {x++; return x;};
private:
int x;
};

int main()
{
M xx;
std::cout << xx.getX() << std::endl;
}

1

Решение

Законно изменять изменяемые файлы в const функции и, конечно, законно изменять изменяемые файлы в non-const функции (как каждый non-const member-variable). mutable Ключевое слово позволяет изменять переменную в const функции, но не дает никаких ограничений на изменение в non-const функции.

3

Другие решения

mutable обычно используется, чтобы позволить const квалифицированные функции-члены для изменения кэшированных данных. Вы можете объявить getX() как const и счастливо изменить xвот для чего изменяем. Однако обычно считается плохой идеей модифицировать внутреннее состояние объекта в функции-члене, которая по своему объявлению говорит, что это не так.

Например, у вас есть функция-член const, которая вычисляет значение на основе содержимого контейнера. Если в контейнере много элементов, получение результата может занять много времени. Если результат изменяется только при добавлении или удалении элементов из контейнера, вы можете кэшировать его для дальнейшего использования. Поскольку функция-член квалифицирована как const, вам необходимо объявить переменную результата как mutable, Поскольку результат может быть рассчитан на основе существующих данных в контейнере, кэшированное значение не считается частью внутреннего состояния объекта, и считается допустимым изменить его с помощью функции const.

int Foo::CalcResult() const
{
if(hasValidCache_ == false)
{

// ... recalc value ...

// Cache the result
hasValidCache = true;
cachedValue_ result;
}

return cachedValue_;
}
0

Утверждение означает это.

class M
{
public:
M(){x=10;};
int getX() const
//           ^^^^^ If a member function is const...

{x++; return x;};
//                 ^^^ ...and it modifies a member variable...
private:
mutable int x;
// ^^^^^^^ ...then that variable must be mutable.
};
0
По вопросам рекламы [email protected]