#c #vector #push #clone
#c #вектор #толкать #клонировать
Вопрос:
Таким образом, push_back
только добавляет копию объекта в вектор моего класса std::vector<Action*>
. У меня есть clone
метод для объектов, которые я помещаю в вектор: stack.push_back(pattern->actions[a]->clone());
где clone возвращает новый объект со всеми теми же свойствами. Неужели это бессмысленно? push_back
Делает то, что я хочу, чтобы он уже делал?
Комментарии:
1. Как объявляется ваш
vector
экземпляр?std::vector<foo>
илиstd::vector<foo *>
, или…?2. @Брайан, обновленный вопрос
3. Ваш вектор не содержит объектов, только указатели. Таким образом, он не может содержать копии объекта.
4. Может быть, использовать смарт-указатель, подобный copy_ptr , который только что придумал мой Google-fu?
5. @Deduplicator скорее
std::unique_ptr
илиstd::shared_ptr
, чем самодельные реализации
Ответ №1:
push_back
сохраняет cpy своего аргумента. Но аргументом является указатель, а не указательница.
Поскольку вы говорите, что Action
это полиморфный тип, мы не можем поступить естественно и просто использовать std::vector<Action>
вместо этого.
Рассмотрите ваши требования, а затем выберите другое решение. Вот некоторые для вас:
- Используйте необработанные указатели, не являющиеся владельцами, и не клонируйте, если вы согласны просто ссылаться на этот объект, и он будет жить достаточно долго.
- Избегайте высокоуровневых конструкций и выполняйте клонирование вручную, как вы показали.
- Рассмотрим
boost::variant
. Тем не менее, вы должны знать все производные классы, когда вы его определяете. - Используйте,
std::unique_ptr
если вектор должен владетьAction
(также см.std::make_unique
). - Используйте,
std::shared_ptr
если он должен делиться собственностью (также см.std::make_shared
). - Используйте
std::weak_ptr
, если вектор не владеет и не должен поддерживать в рабочем состоянииAction
. - Используйте домашнее средство,
copy_ptr
подобное этому, для автоматического клонирования.
Ответ №2:
std::vector<Action*>
хранит указатели на Action
s.
Таким образом, push_back только добавляет копию объекта в std::vector.
Точнее было бы указать, что он добавляет копию указателя на Action
. По большей части, нет, эта предпосылка неверна.
…
stack.push_back(pattern->actions[a]->clone());
гдеclone
возвращается новый объект со всеми теми же свойствами. Это бессмысленно?
Нет, это не бессмысленно. Но это противоречит идиоме. Вместо этого вам следует подумать о создании конструктора копирования, используя std::vector<Action>
(и учитывайте правило трех!).
Комментарии:
1. Если
Action
не является полиморфным типом иclone()
возвращает указатель на один из его производных типов.2. @juanchopanza, да, есть несколько подклассов Action