У меня есть следующее понимание непостоянных переменных в C ++.
Мой вопрос с точки зрения памяти. Где компилятор будет хранить переменную в памяти? Поскольку его можно изменять, то он точно не будет «только для чтения» памяти.
mutable
(изменчивый) это просто спецификатор типа для компилятора, как const
или же volatile
,
Члены класса хранятся в непрерывном фрагменте памяти (кроме статических). Если вы определяете члена как const
, это не значит, что компилятор поместит его в память RO. const
объявление ничего не изменит во время выполнения, это всего лишь ключевое слово для компилятора, чтобы выполнить соответствующие проверки и оптимизации во время компиляции.
Как только вы определите класс (или метод) как const
но вам все еще нужно изменить определенный член этого класса (например, мьютекс или как вы упомянули — для кэширования значения), вы даете компилятору знать, что этот конкретный член mutable
в противном случае вы получите ошибку компиляции.
Предположительно, это зависит от компилятора, но я полагаю, что большинство компиляторов просто решили всегда размещать классы (весь класс) с изменяемыми членами в неконстантной памяти, чтобы учесть это.
Это полностью зависит от компилятора, который может выполнить escape-анализ и определить, что объект никогда не может быть изменен, и в этом случае он может быть записан в read-only
раздел двоичного файла. mutable
спецификатор класса хранения только ослабляет требование времени компиляции.
Объекты должны быть размещены в порядке объявления, поэтому, независимо от спецификатора класса хранения, все переменные находятся в одной и той же области памяти. Однако ничто не помешает read-only
немного из того, чтобы быть установленным на const
регион байтов, если машина его поддерживает.
Все члены класса имеют размер (определяется sizeof
) который как минимум 1
, Это верно для mutable
члены, а также означает, что все члены класса должны занимать некоторый диапазон мест в памяти.
Единственное, что особенного в mutable
членом является то, что его значение может быть изменено, даже если оно находится в пределах const
объект. Это зависит от компилятора, как он этого добивается. Как правило, компилятор обеспечивает константность во время компиляции. Другими словами, если объект const
, его члены логически const
а также делается попытка изменить (или вызватьconst
операции) на любом элементе, тогда код не будет компилироваться, если этот элемент не mutable
,
Там на самом деле нет необходимости в const
объект или его члены, которые должны быть помещены в постоянную память во время выполнения. Если это на самом деле сделано, то потребуется особый режим, чтобы его mutable
изменения участников, даже если изменения других участников запрещены. Например, все члены объекта могут быть помещены в изменяемую память, и только не изменяемые элементы помечены (например, с поддержкой операционной системы), поэтому они не могут быть изменены во время выполнения.
Распространенной причиной использования изменяемых элементов является сохранение результатов дорогостоящих операций, которые можно повторять (дают одинаковые результаты для одних и тех же входных данных). Если результаты не нужны, дорогостоящие операции также не нужны. Если к результату требуется повторный доступ, то изменяемые элементы позволяют сохранять результаты в первый раз, а не многократно выполнять дорогостоящие операции.