Здравствуйте, Дмитро, Вы писали:
Д>Исходя из своего опыта, могу сказать, что в большинстве случаев:
Д>1. const никогда не следует использовать в объявлении методов интерфейсных классов.
А>Не согласен у методов аля "Get", модификатор const должен быть в подавляющем большинстве случаев.
Д>Методы аля "Get" могут возвращать данные, которые могут и не храниться непостредственно в объекте. Они могут читать из файла, делать запросы по сети, устанавливать и разрывать при этом соединения, кешировать эти данные наконец. При этом, возможно, что-то в классе и поменяется. Но пользователю класса нужно только получить эти данные. И его не должно беспокоить каким образом они были получены. Его не должно беспокоить, поменялся ли какой-нибудь внутренний указатель или дескриптор сокета, к которому он все равно доступа, может быть, никогда и не получит. Как получить эти данные -- забота разработчика класса, и я считаю, что он, в свою очередь, не должен заботиться о том, как избавиться от нежелательной константности. Кстати, ты не рискнул сказать "во всех случаях", ты сказал мягче "в подавляющем большинстве случаев". Полагаю, ты сталкивался с теми случаями, когда все же не нужно было делать метод константным.
вот всякие кеширования и прочие временные и вспомогательные радости стоит объявлять mutable, ибо они не определяют
состояние объекта, и, соответственно, не влияют на его константность. А дескриптор сокета, открытого временно и по случаю, не определяет состояние объекта, посему должен быть mutable.
Д>Модификатор const в данном случае навязывает разработчику классов (наследующихся от заданных интерфейсных) некое внутреннее представление и, как следствие, нарушает инкапсуляцию.
А>Не совсем понял.
А>Во-первых сам интерфейс есть некое навязывание. (Не хочешь навязывания, есть замечательный (
) void *, а также возможность сериализовать объект в поток байт
)
А>Во-вторых каким это образом const разрушает инкапсуляцию!?
Д>Интерфейс не навязывает внутреннее представление. Внутренее представление может варьироваться не меняя при этом интерфейса. Собственно, в этом и назначение интерфейса -- оградить пользователя класса от его (класса) внутренностей.
Д>Однако, если я объявляю метод константными, то я подразумеваю, что состояние объекта не будет меняться. Т.е. из всех возможных реализаций заданного класса я отказываюсь от тех, которые меняют состояние (конечно, могу и не отказаться воспользовавшись приемами устранения нежелательной константности). Именно это я подразумевал, когда говорил, что const нарушает инкапсуляцию (кстати, именно нарушает, а не разрушает). Модификатор const навязывает какую-то определенную реализацию. Причем, привязка к реализации делается слишком рано -- на этапе проектирования интерфейсов.
состояние объекта — это тоже деталь его интерфейса, хоть и не оформленная в виде метода.
И если какой-то метод не должен менять состояние объекта, то это должно быть прописано в прототипе этого метода.
А то, как это все устроено внутри объекта, не имеет никакого отношения к его интерфейсу вообще, и к константности методов, в частности.