2013-08-11 3 views
0

Я попытался создать SSCE, потому что это обычно также помогает найти проблему на ранней стадии. Тем не менее, я не могу найти решение для этого, поэтому я хотел бы знать, можно ли определить аргумент, который является неуказанным указателем класса шаблона.Определение параметра в виде неопределенного типа шаблона

У меня есть определенный интерфейс и класс парсера, который должен обрабатывать детали реализации для xerces (например, перекодирование и все эти служебные данные). Класс интерфейса был бы разработан для создания объектов из анализатора (SAX), но без необходимости иметь дело с библиотекой xerces.

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

class Parser 
{ 
    public Parser(IGenericInterface<?> oImpl) {}; 
} 

И в основном я хотел бы знать, как это может быть сделано в C++. В приведенном ниже примере я получаю ошибку компилятора в строке, объявляющей переменную интерфейса, потому что ей не хватает типа. Но, конечно, в объявлении класса тип неизвестен и должен быть назначен во время выполнения, как показано в main.

#include <iostream> 
#include <string> 

template <class T> 
class IGenericInterface 
{ 
public: 
    IGenericInterface() {}; 
    virtual ~IGenericInterface() {}; 

    virtual T *createInstance(void) = 0; 
}; 

template <class T> 
class Implementation : public IGenericInterface<T> 
{ 
public: 
    Implementation() {}; 
    virtual ~Implementation() {}; 

    T *createInstance(void) 
    { 
     T * t = new T; 
     return t; 
    } 
}; 

class Parser 
{ 
public: 
    Parser(IGenericInterface *oImpl) { mImpl = oImpl; }; 
    virtual ~Parser() { delete mImpl; }; 

    void doSomething(void) { do whatrever is needed; t = createInstance(); }; 

private: 
    IGenericInterface *mImpl; 
}; 

int main() 
{ 
    Parser *p = new Parser(new Implementation<int>()); 
    sleep(3); 

    return 0; 
} 

Итак, как я должен определить Parser конструктор, чтобы сделать его передать произвольный интерфейс аргумент?

+0

Похоже, что ваш парсер зависит от шаблона аргумента '' IGenericInterface , так почему не 'Parser' шаблон тоже? – dyp

+0

Не стесняйтесь процитировать ошибки компилятора дословно. Указывая, какой номер строки там, где также редко болит. –

+0

В вашем примере никогда не используется 'CreateInstance'. Мне немного бессмысленно определять шаблон, если вы не собираетесь использовать единственное, что он предлагает. Как вы планируете использовать «CreateInstance»? –

ответ

0

Поскольку, по-видимому, общий вид, как в Java, не может быть реализован на C++, я нашел другое решение, которое также позволяет мне детализировать детализированный синтаксический анализатор.

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

картина будет выглядеть так:

template <class T> 
class ISerialization 
{ 
public: 
    virtual ~ISerialization(void) {}; 

public: 
    virtual std::string serialize(void) = 0; 
    virtual bool deserialize(std::vector<T *> &oObjects, std::string const &oSerialized) = 0; 
}; 

class parser 
{ 
    void parsing(void) { abstract_function(); } 
    virtual void abstract_function() = 0; 
}; 


class implementation : public ISerialization<Task>, public parser 
{ 
    std::string serialize(void) {}; 
    bool deserialize(std::vector<T *> &oObjects, std::string const &oSerialized) {}; 
    void abstract_function() { specific implementation goes here}; 
}; 
1

Смешивание статический и динамический полиморфизм является не идти (исключения не могут применяться)

template <class T> 
class IGenericInterface 
{ 
public: 
    IGenericInterface() {}; 
    virtual ~IGenericInterface() {}; 

    virtual T *createInstance(void) = 0; 
}; 

И ваше использование указателей кошмар.

1

C++ - это статический язык, поэтому во время компиляции любые типы должны быть разрешены. Следовательно, то, что вы делаете в java, не может быть сделано аналогичным образом на C++. Вместо этого вы используете либо динамический полиморфизм (используя наследование), либо «статический полиморфизм», используя шаблоны (разрешенные во время компиляции) с помощью CRTP.

+0

Итак, с помощью 'using inheritance' вы имеете в виду, что в моем классе реализации я должен наследовать парсер напрямую? Это может сработать? – Devolus

+0

Подумав о наследовании, я нашел шаблон, который работает. Мне нравится java-подход лучше, потому что вы можете строго отделить объекты, но так как это невозможно в C++, я нашел решение, которое тоже нормально. Я могу отправить пример в качестве ответа. – Devolus

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