C — Клонирование в вектор

#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> вместо этого.

Рассмотрите ваши требования, а затем выберите другое решение. Вот некоторые для вас:

  1. Используйте необработанные указатели, не являющиеся владельцами, и не клонируйте, если вы согласны просто ссылаться на этот объект, и он будет жить достаточно долго.
  2. Избегайте высокоуровневых конструкций и выполняйте клонирование вручную, как вы показали.
  3. Рассмотрим boost::variant . Тем не менее, вы должны знать все производные классы, когда вы его определяете.
  4. Используйте, std::unique_ptr если вектор должен владеть Action (также см. std::make_unique ).
  5. Используйте, std::shared_ptr если он должен делиться собственностью (также см. std::make_shared ).
  6. Используйте std::weak_ptr , если вектор не владеет и не должен поддерживать в рабочем состоянии Action .
  7. Используйте домашнее средство, 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