Наследование в C ++: вызов функции подкласса шаблона

0

У меня есть шаблонный класс и подкласс шаблонного класса, чтобы реализовать функцию по-разному. Поскольку я хочу сохранить гибкость в наличии нескольких подклассов, я не непосредственно храню сам подкласс. В Java что-то вроде того, что я пытаюсь сделать, будет работать, но, видимо, это не в C++.

template<class Res> class Loader {
public:
    Res* loadFromFile(std::string filePath);
};


template<class Res> inline Res* Loader<Res>::loadFromFile(std::string filePath){return NULL;}

Подкласс:

class TextureLoader : public Loader<sf::Texture> {
public:
    sf::Texture* loadFromFile(std::string path);
};

inline sf::Texture* TextureLoader::loadFromFile(std::string path){
    sf::Texture* texture = new sf::Texture();
    texture->loadFromFile(path);
    return texture;
}

Где-то в другом классе я храню экземпляр Loader:

Loader<Res> * loader;

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

  • 0
    loadFromFile должен быть virtual
  • 0
    @InnocentBystander Я пытался сделать его виртуальным, но потом компилятор жалуется на ошибки компоновщика.
Теги:
templates
inheritance

3 ответа

2
Лучший ответ

Возможно, вам не требуется наследование - похоже, что вам может понадобиться специализация:

template<>
sf::Texture* Loader<sf::Texture>::loadFromFile(std::string path) {...}

Теперь просто используйте Loader<sf::Texture> где перед тем, как вы планируете использовать TextureLoader. Или, typedef последнего к первому.

  • 0
    Это именно то, что я хотел сделать, спасибо большое!
1

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

template<class T> class Loader 
{
public:
   virtual T* LoadFromFile(const std::string& filePath) = 0;
   virtual ~Loader() {}
};

class TextureLoader : public Loader<sf::Texture>
{
public:
   virtual sf::Texture* LoadFromFile(const std::string& filePath);
   {
     sf::Texture* texture = new sf::Texture();
     texture->loadFromFile(path);
     return texture;
   }
};
1

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

template<class Res> class Loader {
public:
    virtual ~Loader() [}
    virtual Res* loadFromFile(std::string filePath);
};
  • 0
    Я бы предпочел CRTP или специализацию как лучшее решение с шаблонами.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню