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

C++ Inheritance: Calling subclass function of template

我有一个模板化 class 和一个模板化 class 的子 class,以便以不同的方式实现功能。因为我想保持拥有多个 subclass 的灵​​活性,所以我不直接存储 subclass 本身。在 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:

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;
}

在另一个地方的某个地方 class 我存储了一个 Loader 的实例:

Loader<Res> * loader;

我的问题是,即使我将 TextureLoader 实例分配给该加载程序变量,也只会调用 superclass 函数,而不是实际实现的 subclass 函数。如何在保持拥有多个加载器的灵活性的同时调用子类函数?

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

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

您的函数从未被标记为虚拟。也就是说,你真的应该把它抽象化,因为不覆盖它就没有用:

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;
   }
};

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

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

现在只需在您计划使用 TextureLoader 的地方使用 Loader<sf::Texture>。或者,将后者类型定义为前者。