Всем привет! Ко мне через личку обратились товарищи, сказав что, они не хотят комментировать, то что не поняли или поняли не до конца и попросили дать пояснения. На основе присланных вопросов я попытаюсь дать ответы в доступной форме. В С++ есть физическая и логическая константность. Физическая означает, что объект никак не меняется (кроме грубой силы). Логическая означает, что объект внешне неизменен, но может поменять внутреннее состояние. Например, Объект изменился. Где это можно встретить: Есть ситуации, когда нам такие сюрпризы не нужны. Создаем изначально иммутабельный объект: пользуемся или пока нету оператора .: Объект test остался неизменным. Где это нужно: 1) в параллельном программировании;
2) при работе с «вещью в себе» и мы не хотим сюрпризов. Начну с примера: Есть константный объект и функция Это может быть нарушение, может быть ошибка, но компилятор даже не пикнет. Рассмотрим другую ситуацию. Есть иммутабельный объект: и Компилятор будет ругаться. Ломануть можно только с помощью reinterpret_cast, с которым можно обломаться, если защищаемый объект хранить нестандартным образом (например, в сжатом/зашифрованном/сериализованном виде) . Тот же эффект и при Примение Immutable, говорит что объект не должен меняться. Не буду говорить про ФП, агентно-ориентированное программирование, про модель акторов и классной доски, а скажу про параллельное программирование (модель акторов и классной доски там активно используются).  И скажу сначала в неформальном, несколько утрированном виде. Предположим на git (или на другой системе контроля версий) есть проект. Есть N программистов. Каждый должен сделать свою версию проекта. Что делается: Итог, исходный проект цел, начальник может выбирать из fork-ов. Перенося это в параллельное программирование: Иммутабельность говорит, что при работе с ними нету сюрпризов. Это вопрос вопрос вкуса, но представляется, что выражение вида выглядит понятнее чем т.к, иммутабельность сразу говорит что объект никак не должен меняться, что константность используется как для адреса, так и для содержимого. Это тоже вопрос вкуса. Но реализация сделана в соответствии с принципами ФП, при этом оставляя возможности для эффективной работы в стиле С++. См. «Оверхед». Вы можете пользоваться как универсальным классом Immutable, так и вспомогательными классы immutable::array, immutable::pointer и т. д. Эти вспомогательные классы не связаны друг с другом. Вы можете делать объект изначально иммутабельным и передавать его по ссылке. Копии можете делать при необходимости. Никто не заставляет вас пользоваться тем, что не используете. Если Вы хотите работать с внутренними данными, то можете получить ОДИН раз копию внутренних данных и работать с ними. Для этого есть функция value. Здесь можно возразить, что получив доступ к внутренним данным, можно испортить иммутабельность. Во-первых, value возвращает константные данные, а во-вторых это уже сознательные действия программиста. Многие библиотечные классы возвращают нативное представление объектов, играя с которым можно нагадить. Но это, еще раз, программист получает внутренние данные, причем в данном случае константные, и это СОЗНАТЕЛЬНЫЕ действия программиста. Для дальнейшего изучения рекомендую: Мэтью Уилсон «Практический подход к решению проблем программирования С++»:
автор книги предлагает реализацию, того чего ему не хватает в С++ (до С++11, но часть вопросов актуальна и ныне), например property и т. д. Андрей Александреску «Язык программирования D», стиль у него своеобразный, но интересно почитать, как в ЯП встроено контрактное программирование.