Я довольно новичок в C ++ (с Java опытом) и пытаюсь понять принципы и методы проектирования классов.
Из того, что я уже прочитал, мне кажется, что следует предпочесть, чтобы члены класса были объектами, а не указателями (или ссылками). - Пожалуйста, исправьте меня, если это как-то не так.
Исходя из этого, вот мой дизайн (версия 1):
class Outer {
Some_type _member;
Inner _inner;
};
class Inner {
Some_type* _ptr_to_outer_member;
};
Я знаю, что время жизни ссылочного объекта (Outer._member)
необходимо гарантированно превышать время жизни ссылающегося объекта (Inner)
и его указателя _ptr_to_outer_member
, чтобы избежать висящего указателя. Здесь это условие должно быть удовлетворено тем фактом, что _inner
является составной частью _outer
, а Outer._member
является членом объекта, поэтому он всегда инициализируется.
Теперь мне, конечно, не нужно Outer
быть копируемым. Даже быть подвижным не обязательно, поскольку его нельзя перемещать после того, как все настроено, хотя было бы удобно иметь его подвижным при создании других объектов. Во всяком случае с этим дизайном, когда Outer
перемещается _inner._ptr_to_outer_member
становится недействительным. - Этого можно избежать, отключив операции копирования и перемещения для Outer
, но кажется, что это просто обходная практика. Есть руководство, которое гласит, что следует избегать хранения ссылок на переменные, выделенные стеком, и в этом случае мне кажется, что у него могут быть аналогичные причины, которых следует избегать.
Альтернатива, которую я вижу, состоит в том, чтобы выделять кучу _member
следующим образом ( версия 2):
class Outer {
std::unique_ptr<Some_type> _member;
Inner _inner;
};
class Inner {
Some_type* _ptr_to_outer_member;
};
Outer
теперь можно перемещать и не копировать. Это то, что я хочу, но за счет кучи, выделяющей _member
, что противоречит рекомендациям о предпочтении членов объекта.
Таким образом, у меня возникает вопрос: есть ли какие-либо рекомендации по этому поводу? Я имею в виду что-то вроде использования указателя на объект в качестве членов, когда вы хотите поделиться объектом (как в версии дизайна 2) - это, вероятно, будет наиболее разумным для меня (если я что-то упустил). Или просто отключить перемещение для таких объектов (как в версии дизайна 1) и иметь дело с ним, поскольку оно неподвижно.
Или в примерах что-то принципиально не так?
Заранее спасибо для любого понимания этого.