Как вернуть копию производного объекта в вектор базовых классов?

Вот проблема, у меня есть вектор указателей на абстрактный базовый класс, заполненный производными объектами, вот так:

class AbstractBase { /* ... */ };

clase Derived1 : public AbstractBase {
Derived1() { }
Derived1( const AbstractBase& abc ) { /* ... */ }
};

/* ... */

vector< AbstratcBase* > lThingies;

const AbstractBase& getThingie(int pos) {
return *lThingies[pos];
}

И чтобы получить копии элементов, я использую производный класс «конструктор копирования» следующим образом:

Derived1 d1 = getThingie(2);

Но проблема в том, что мне это не нравится: нет способа принудительно реализовать этот «конструктор копирования» при создании класса «output42», и даже если вы помните, очень легко ошибиться (например, сделать это). рекурсивный вызов, случилось со мной).

Мой вопрос: Есть лучший способ сделать это? как?

Обновить:
Одно из «неписаных» требований решения, которое я ищу, — это получить копию полученный объект как локальная переменная, поэтому я не забываю удалять Это.

Больше информации:
Есть ряд lThingies и во время выполнения я могу сказать, какие производные объекты содержатся в (производный1, производный2 и т. д.), но не во время компиляции.

0

Решение

Вы знаете свой getThingie возвращает Derived1? Если вы знаете это, возможно, вам следует изменить тип возвращаемого значения Derived1 и хранение в std::vector быть Derived1 вместо AbstractBase,

Предполагая, что выше не работает, вы можете сделать Derived1 bob = dynamic_cast<Derived1&>(getThingie(...));, который во время выполнения проверяет, что вещь Derived1 или более производный экземпляр, и если это так, он выполняет приведение — если нет, он генерирует исключение.

Если вы не хотите беспокоиться о проверке времени выполнения, потому что вы настолько уверены, что это Derived1, просто используйте Derived1 bob = static_cast<Derived1&>(getThingy(...));,

Однако работа с реальными экземплярами классов, которые имеют иерархию наследования, очень сомнительна. Есть много, много вещей, которые могут пойти не так.

0

Другие решения

Вы могли бы сделать чисто виртуальный clone функция в AbstractBase который возвращает AbstractBase указатель и переопределение clone в ваших производных классах.


СТРОГО МНЕНИЕ:

Хотя это своего рода грубая и устаревшая практика (на мой взгляд). Я предлагаю ре-архитектуру, чтобы устранить необходимость делать это в первую очередь.

Для того, чтобы разработать на моем «грубое и устаревшее» мнение виртуального конструктора идиомы (я уверен, что это будет спорным):

  • Чтобы действительно быть устойчивым / универсальным клоном, нужно было бы создать шаблон для распределителя, как это делают некоторые конструкции STL. Но это не может быть.
  • Когда вы действительно хотите скопировать объект, о котором вы не знаете конкретный тип? Я подвергаю сомнению законность этого варианта использования.
4

class A
{
public:
virtual void toto() { std::cout << "Love Java" <<std::endl; }
virtual A&& Duplicate() { return std::move(A()); }
};

class B : public A
{
public:
virtual void toto() { std::cout << "Love C++11" <<std::endl; }
virtual B&& Duplicate() { return std::move(B()); }
};

int main()
{
A *a = new B();;

A&& b(a->Duplicate());

a->toto();
b.toto();
}

В основном вы создаете B в стеке, не зная его типа. (со ссылкой на rvalue в c ++ 11)

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector