C ++继承:调用模板的子类函数

时间:2015-01-01 15:15:37

标签: c++ templates inheritance

我有一个模板化的类,以及模板化类的子类,以便以不同的方式实现一个函数。因为我想保持具有多个子类的灵活性,所以我不直接存储子类本身。在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实例分配给该加载器变量,也只调用超类函数,而不是实际实现的子类函数。如何在保持多个加载器的灵活性的同时调用子类函数?

3 个答案:

答案 0 :(得分:2)

您可能不想要继承 - 看起来您可能需要专业化:

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

现在只需在计划使用Loader<sf::Texture>之前使用TextureLoader。或者,将后者命名为前者。

答案 1 :(得分:1)

为了进行动态调度,您需要在基类中声明成员函数virtual。您还需要将析构函数声明为虚拟,以确保在通过基类类型删除派生类时对其进行正确清理。

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

答案 2 :(得分: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;
   }
};