Только getName3
нарушает const-правильность, потому что _name
является постоянным (в частности, const std::string &
) в теле функции, а std::string::operator=
является не const
.
getName2
плохой дизайн, потому что он требует изменяемого контекста, даже если он не выполняет никаких мутаций, поэтому он должен быть объявлен const
, так как в противном случае это привело бы к неожиданным ограничениям,то есть вы не можете вызывать его через const Person &
.
Вы также можете добавить в смесь корректность «volatile» и «rvalue», которые похожи по духу.
Корректность константности может бытьчувствуется через его нелокальные эффекты.Типичными примерами являются реляционные операторы (operator<
и operator==
): если вы не пометите их как const
, многие стандартные алгоритмы и контейнеры не будут работать с вашим классом, поскольку они обычно применяют операторы к ссылкам на константные элементы,В этом смысле отсутствие «как можно более постоянного» накладывает ненужные ограничения на использование вашего кода.С противоположной точки зрения, то же самое применимо, если ваши собственные функции излишне требуют изменяемой ссылки на объект, так как это лишит вас необходимости использовать постоянные ссылки и лишит вас проверок во время компиляции, что операция, которую вы думалибыл не мутировавшим, фактически не мутировал объект.