Ответ 1
Есть несколько причин, по которым возвращение ссылок (или указателей) на внутренности класса плохое. Начиная с (что я считаю) самым важным:
-
Инкапсуляция нарушена: вы протекаете детали реализации, а это значит, что вы больше не можете изменять свои внутренние элементы своего класса по своему усмотрению. Если вы решили не хранить
first_
, например, но вычислить его на лету, как бы вы вернули ссылку на него? Вы не можете, таким образом, вы застряли. -
Инвариантный больше не является устойчивым (в случае неконстантной ссылки): любой может получить доступ и изменить атрибут, упомянутый по желанию, таким образом, вы не сможете "отслеживать" его изменения. Это означает, что вы не можете сохранить инвариант, частью которого является этот атрибут. По сути, ваш класс превращается в blob.
-
Проблемы с временем жизни spring вверх: легко сохранить ссылку или указатель на атрибут после того, как исходный объект, к которому они принадлежат, перестает существовать. Это, конечно, поведение undefined. Большинство компиляторов будут пытаться предупреждать о сохранении ссылок на объекты в стеке, например, но я не знаю компилятора, которому удалось создать такие предупреждения для ссылок, возвращаемых функциями или методами: вы сами.
Таким образом, обычно лучше не выделять ссылки или указатели на атрибуты. Даже не const!
Для небольших значений обычно достаточно передать их копией (как in
, так и out
), особенно теперь с семантикой перемещения (по пути в).
Для больших значений это действительно зависит от ситуации, иногда прокси-сервер может облегчить ваши проблемы.
Наконец, обратите внимание, что для некоторых классов наличие публичных участников не так уж плохо. Какой смысл заключать элементы a pair
? Когда вы обнаруживаете, что пишете класс, который представляет собой не более чем набор атрибутов (никаких инвариантов вообще), вместо того, чтобы получать все OO на нас и писать пару геттер/сеттер для каждого из них, подумайте о том, чтобы сделать их общедоступными.