Существует несколько причин, по которым возврат ссылок (или указателей) на внутренние компоненты класса является плохим.Начиная с (что я считаю) самого важного:
Инкапсуляция нарушена: вы пропускаете детали реализации, что означает, что вы больше не можете изменять свойклассы по вашему желанию.Если вы решили не хранить first_
, например, а вычислить его на лету, как бы вы вернули ссылку на него?Вы не можете, поэтому вы застряли.
Инвариант больше не является устойчивым (в случае неконстантной ссылки): любой может получить доступ и изменить указанный атрибутпо желанию, таким образом, вы не можете «отслеживать» его изменения.Это означает, что вы не можете поддерживать инвариант, частью которого является этот атрибут.По сути, ваш класс превращается в BLOB-объект.
Время жизни проблемы возникают: легко сохранить ссылку или указатель на атрибут после исходного объекта, которому они принадлежатперестать существовать.Это, конечно, неопределенное поведение.Например, большинство компиляторов будут пытаться предупредить о сохранении ссылок на объекты в стеке, но я не знаю ни одного компилятора, который мог бы выдавать такие предупреждения для ссылок, возвращаемых функциями или методами: вы сами по себе.
Поэтому лучше не давать ссылки или указатели на атрибуты. Даже не константные!
Для небольших значений обычно достаточно передать их копией (как in
, так и out
), особенно сейчас с семантикой перемещения (в путив).
Для больших значений это действительно зависит от ситуации, иногда прокси может облегчить ваши проблемы.
Наконец, обратите внимание, что для некоторых классов наличие открытых членов не так уж плохо.Какой смысл заключать в капсулу членов pair
?Когда вы обнаружите, что пишете класс, который является не более чем набором атрибутов (без каких-либо инвариантов), тогда вместо того, чтобы брать на себя всю ОО и писать пару геттер / сеттер для каждого из них, рассмотрите возможность сделать их открытыми.