Ключевое слово mutable
- это способ проникнуть сквозь вуаль const
, которую вы накрываете своими объектами. Если у вас есть константная ссылка или указатель на объект, вы не можете изменить этот объект каким-либо образом , кроме , когда и как он помечен mutable
.
С вашей const
ссылкой или указателем вы обязаны:
- доступ только для чтения для всех видимых элементов данных
- разрешение на вызов только тех методов, которые помечены как
const
.
Исключение mutable
делает его таким образом, что теперь вы можете записывать или устанавливать элементы данных, помеченные mutable
. Это единственное внешне видимое отличие.
Внутренне те const
методы, которые вам видны, также могут записывать в элементы данных, помеченные mutable
. По существу, постоянная завеса всесторонне прокалывается. Разработчик API должен убедиться, что mutable
не разрушает концепцию const
и используется только в полезных особых случаях. Ключевое слово mutable
помогает, потому что оно четко помечает элементы данных, на которые распространяются эти особые случаи.
На практике вы можете использовать const
навязчиво по всей вашей кодовой базе (вы, по сути, хотите «заразить» вашу кодовую базу «болезнью» const
). В этом мире указатели и ссылки const
за очень немногими исключениями дают код, который легче рассуждать и понимать. Для интересного отступления ищите «ссылочную прозрачность».
Без ключевого слова mutable
вы в конечном итоге будете вынуждены использовать const_cast
для обработки различных полезных особых случаев, которые он позволяет (кэширование, подсчет ссылок, отладка данных и т. Д.). К сожалению, const_cast
значительно более разрушителен, чем mutable
, потому что заставляет API client разрушить защиту const
объектов, которые он использует. Кроме того, это вызывает повсеместное const
разрушение: const_cast
использование константного указателя или ссылки позволяет беспрепятственную запись и вызов метода для доступа к видимым элементам. В отличие от этого mutable
требует, чтобы разработчик API осуществлял детальный контроль над исключениями const
, и обычно эти исключения скрыты в const
методах, работающих с личными данными.
(NB. Я несколько раз ссылаюсь на данные и метод visibility . Я говорю о членах, помеченных как открытые или закрытые или защищенные, что является совершенно другим обсуждаемым типом защиты объектов здесь .)