简体   繁体   English

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

[英]Polymorphism with smart pointers using templates

I'm having trouble putting a shared_ptr of sf::Text, sf::Sprite and sf::Text into an array of shared_ptr 我在将sf :: Text,sf :: Sprite和sf :: Text的shared_ptr放入shared_ptr数组中时遇到麻烦
sf::Drawable is the mother class of all the above and is abstract sf :: Drawable是以上所有方法的父类,并且是抽象的
Here's the game engine function: 这是游戏引擎功能:

GameEngine.h 游戏引擎

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

GameEngine.cpp GameEngine.cpp

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

Rendering.cpp 渲染文件

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

I'm getting the following error in VS 2015: 我在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)

Is there a way to put a shared pointer of a subclass into an array of shared pointers of its mother class? 有没有一种方法可以将子类的共享指针放入其母类的共享指针数组中?

EDIT: 编辑:
An answer said that: 回答说:

Just because Sprite is a subclass of Drawable, does not mean that shared_ptr<Sprite> is a subclass of shared_ptr<Drawable> . 仅仅因为Sprite是Drawable的子类,并不意味着shared_ptr<Sprite>shared_ptr<Drawable>的子类。

Then why can i do this? 那我为什么可以这样做?

class A{};

class B : public A {};

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

Just because Sprite is a subclass of Drawable , does not mean that shared_ptr<Sprite> is a subclass of shared_ptr<Drawable> . 仅仅因为SpriteDrawable的子类,并不意味着shared_ptr<Sprite>shared_ptr<Drawable>的子类。

When the compiler sees this: 当编译器看到以下内容时:

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

it looks for a member function add(shared_ptr<sf::Sprite>) following the overload resolution rules. 它根据重载解析规则寻找成员函数add(shared_ptr<sf::Sprite>)

Even though shared_ptr<Sprite> is not a subclass of shared_ptr<Drawable> , there is an implicit conversion available, so it would be a candidate. 即使shared_ptr<Sprite>不是shared_ptr<Drawable>的子类,也可以使用隐式转换,因此它将是候选对象。

However this: 但是,这:

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

provides a declaration of the function for any type, but no definition . 提供任何类型的函数声明 ,但没有定义 Therefore it provides an exact match and will be chosen by the compiler. 因此,它提供了完全匹配的结果,将由编译器选择。 That is why you get linker errors. 这就是为什么您得到链接器错误。

One way to solve this is to use std::static_pointer_cast , like this: 解决此问题的一种方法是使用std :: static_pointer_cast ,如下所示:

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

I would also reconsider if/why you need the template above - I can't see what purpose that is serving, other than to give you link time errors instead of compile time errors. 我还会重新考虑是否/为什么需要上面的模板-除了给您链接时间错误而不是编译时间错误之外,我看不到它的目的是什么。

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

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