Нет золотого правила, которое применяется 100% времени. Это действительно суждение в зависимости от ваших потребностей.
Это зависит от того, какую функциональность вы хотите скрыть / запретить оружию от доступа к Solider.
Если вы хотите иметь доступ только к ружью только для чтения, вы можете вернуть постоянную ссылку своему члену.
Если вы хотите предоставить только определенные функции, вы можете создать функции-оболочки. Если вы не хотите, чтобы пользователь пытался изменить настройки пистолета через солдата, сделайте функции обертки.
В целом, хотя я и вижу Оружие как его собственный объект, и если вы не возражаете против раскрытия всей функциональности Оружия, и не против, чтобы что-то изменилось через объект Солдата, просто сделайте его публичным.
Возможно, вам не нужна копия пистолета, поэтому, если вы используете метод GetGun (), убедитесь, что вы не возвращаете копию пистолета.
Если вы хотите, чтобы ваш код был простым, тогда поручите солдату разобраться с оружием. Ваш другой код должен работать с пистолетом напрямую? Или солдат всегда может знать, как работать / перезаряжать свое оружие?