2015-01-15 3 views
0

Я пытаюсь создать список объектов шаблона, которые шаблоны после разных подклассов базового класса. Я знаю, что списки не могут быть гетерогенными, поэтому typedef'd мой список шаблонов после списка этих базовых классов.Создание объектов подкласса из базового шаблона списка

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

Все это делается в заголовке.

// Base Class 
class MyBase { 
public: 
    MyBase(int a) {} 

    virtual void Print() = 0; 
}; 

// Subclass ONE 
class MySub_One : 
    public MyBase 
{ 
public: 
    MySub_One(int a) 
     : MyBase(a) {} 

    virtual void Print() override { printf("Sub One\n"); } 
}; 

// Subclass TWO 
class MySub_Two : 
    public MyBase 
{ 
public: 
    MySub_Two(int a) 
     : MyBase(a) {} 

    virtual void Print() override { printf("Sub Two\n"); } 
}; 



// Template Class 
template <class T> 
class MyTemplate 
{ 
    int numPrint; 

    void CreateAndPrint() 
    { 
     T* obj = new T(0); // Compiler says, "error C2259: 'MyBase' Cannot instantiate abstract class." 

     obj = dynamic_cast<MyBase>(obj); 
     obj->Print(); 
    } 
}; 

Когда я позже добавить объект подкласса в список BaseClass, есть также проблема:

list<MyTemplate<MyBase>*> testList = list<MyTemplate<MyBase>*>(); 
testList.push_back(new MyTemplate<MySub_One>()); // This is a problem too 

Что вызывает эти две ошибки? Есть ли способ сделать эту работу?

ответ

2

Есть пара проблем.

  1. MyTemplate<MyBase> не является базовым классом MyTemplate<MySub_One>

  2. Вы пытаетесь добавить указатель типа MyTemplate<MySub_One>* в список, который должен держать список объектов типа MyTemplate<MyBase>.

Вам нужно что-то вроде:

class TemplateBase 
{ 
    public: 
    virtual void CreateAndPrint() = 0; 
}; 

template <class T> 
class MyTemplate : public TemplateBase 
{ 
    public: 
    virtual void CreateAndPrint() 
    { 
     T* obj = new T(0); 
     obj->Print(); 
    } 
}; 

list<TemplateBase*> testList; 
testList.push_back(new MyTemplate<MySub_One>()); 
+0

1. Это было на самом деле опечатка - оригинал был список указателей. Добавление указателя к вышеуказанному коду не имело никакого значения. Однако ... 2. Я попробую это - выглядит многообещающим. – JordanBell

Смежные вопросы