Дублирующий подкласс абстрактного базового класса - PullRequest
1 голос
/ 02 февраля 2011

У меня есть абстрактный базовый класс, чтобы заставить некоторые подклассы перегружать оператор <<. </p>

Я храню несколько указателей на экземпляры этих подклассов в std :: stack ... В некоторыхЯ хочу дублировать верхний элемент стека (и поместить его сверху).

Проблема в том, что я не могу создать экземпляр абстрактного класса.И, очевидно, поскольку я хочу сделать это для каждого из моих подклассов, я не буду знать тип ...

Интересно, возможно ли это даже без добавления другого чисто виртуального метода (скажем, «Базовый * клон» () = 0 ') и реализовать его в каждом из моих подклассов?Конечно, должен быть более чистый путь.

Ответы [ 2 ]

4 голосов
/ 02 февраля 2011

Я думаю, вам действительно нужен метод Clone в этом случае.Вы хотите динамически копировать элемент подкласса во время выполнения, и обычный способ изменить поведение во время выполнения - это виртуальные методы.Без использования какого-либо виртуального метода у вас не было бы способа выяснить, какой это ребенок.Возможно, вы могли бы использовать CRTP для автоматического создания этого клона для вас, хотя:

// Totally uncompiled and untested.
class Base
{
public:
    virtual Base* Clone() const = 0;
};

template <class T>
class Child : public Base
{
public:
    virtual Base* Clone() const { return new T(*static_cast<T*>(this)); }
protected:
    Child(); // Can't instantiate directly
    Child(const Child& right); // Can't instantiate directly
};

class Grandchild : public Child<Grandchild>
{
    // Clone should do the right thing.
};
0 голосов
/ 02 февраля 2011

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

Вам нужно будет либо реализовать свой собственный набор текста. другими словами, есть виртуальная функция, которая возвращает тип класса, а затем создать соответствующий класс

Или разрешите RTTI (Информация о типе времени выполнения) сделать то же самое. поскольку RTTI влияет на каждый класс, возможно, более эффективно создать собственный метод typeof.

Тогда вы можете

  1. Поп указатель
  2. Получить тип
  3. Установить правильный класс, используя конструктор копирования, вероятно, в переключатель
  4. Вставить оба обратно в стек

psuedocode

 base* ptr = stack.pop()
 base *copy
 switch (ptr->typeof()) {
  case class1type : copy = new class1(ptr) break;
  case class2type : copy = new class2(ptr) break;
  ...
}

stack.push (ptr)
stack.push(copy)

DC

...