繁体   English   中英

使用模板的智能指针进行多态

[英]Polymorphism with smart pointers using templates

我在将sf :: Text,sf :: Sprite和sf :: Text的shared_ptr放入shared_ptr数组中时遇到麻烦
sf :: Drawable是以上所有方法的父类,并且是抽象的
这是游戏引擎功能:

游戏引擎

template<class T>
    void add(std::shared_ptr<T> actor);

GameEngine.cpp

template<>
void GameEngine::add<sf::Drawable>(std::shared_ptr<sf::Drawable> actor)
{
    drawables.insert(actor);
}

渲染文件

void Rendering::addDrawable(std::shared_ptr<sf::Sprite> sprite, sf::Vector2i texture_rect, const char* texture_name)
{
    sf::Texture* _texture = engine.lock()->getGameData().getTexture(texture_name);
    if (_texture) {
        sprite->setTexture(*_texture);
        sprite->setTextureRect(sf::IntRect(0, 0, texture_rect.x, texture_rect.y));
        //What do i have to put in the below function?
        engine.lock()->add(sprite);
    }
}

我在VS 2015中遇到以下错误:

1>Rendering.obj : error LNK2019: symbole externe non résolu "public: void __thiscall GameEngine::add<class sf::Sprite>(class std::shared_ptr<class sf::Sprite>)" (??$add@VSprite@sf@@@GameEngine@@QAEXV?$shared_ptr@VSprite@sf@@@std@@@Z) référencé dans la fonction "public: void __thiscall Rendering::addDrawable(class std::shared_ptr<class sf::Sprite>,class sf::Vector2<int>,char const *)" (?addDrawable@Rendering@@QAEXV?$shared_ptr@VSprite@sf@@@std@@V?$Vector2@H@sf@@PBD@Z)
1>Rendering.obj : error LNK2019: symbole externe non résolu "public: void __thiscall GameEngine::add<class sf::Shape>(class std::shared_ptr<class sf::Shape>)" (??$add@VShape@sf@@@GameEngine@@QAEXV?$shared_ptr@VShape@sf@@@std@@@Z) référencé dans la fonction "public: void __thiscall Rendering::addDrawable(class std::shared_ptr<class sf::Shape>,char const *)" (?addDrawable@Rendering@@QAEXV?$shared_ptr@VShape@sf@@@std@@PBD@Z)
1>Rendering.obj : error LNK2019: symbole externe non résolu "public: void __thiscall GameEngine::add<class sf::Text>(class std::shared_ptr<class sf::Text>)" (??$add@VText@sf@@@GameEngine@@QAEXV?$shared_ptr@VText@sf@@@std@@@Z) référencé dans la fonction "public: void __thiscall Rendering::addDrawable(class std::shared_ptr<class sf::Text>,char const *,char const *,class sf::Color)" (?addDrawable@Rendering@@QAEXV?$shared_ptr@VText@sf@@@std@@PBD1VColor@sf@@@Z)

有没有一种方法可以将子类的共享指针放入其母类的共享指针数组中?

编辑:
回答说:

仅仅因为Sprite是Drawable的子类,并不意味着shared_ptr<Sprite>shared_ptr<Drawable>的子类。

那我为什么可以这样做?

class A{};

class B : public A {};

int main() {
    std::vector<std::shared_ptr<A>> ar;
    ar.push_back(std::make_shared<B>());
    return 0;
}

仅仅因为SpriteDrawable的子类,并不意味着shared_ptr<Sprite>shared_ptr<Drawable>的子类。

当编译器看到以下内容时:

engine.lock()->add(sprite);

它根据重载解析规则寻找成员函数add(shared_ptr<sf::Sprite>)

即使shared_ptr<Sprite>不是shared_ptr<Drawable>的子类,也可以使用隐式转换,因此它将是候选对象。

但是,这:

template<class T>
    void add(std::shared_ptr<T> actor);

提供任何类型的函数声明 ,但没有定义 因此,它提供了完全匹配的结果,将由编译器选择。 这就是为什么您得到链接器错误。

解决此问题的一种方法是使用std :: static_pointer_cast ,如下所示:

engine.lock()->add(std::static_pointer_cast<Drawable>(sprite));

我还会重新考虑是否/为什么需要上面的模板-除了给您链接时间错误而不是编译时间错误之外,我看不到它的目的是什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM