使用模板的智能指针的多态性
Polymorphism with smart pointers using templates
我无法将 sf::Text、sf::Sprite 和 sf::Text 的 shared_ptr 放入 shared_ptr
的数组中
sf::Drawable 是以上所有的母亲 class 并且是抽象的
这是游戏引擎函数:
GameEngine.h
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);
}
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);
}
}
我在 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)
有没有办法将子class的共享指针放入其母class的共享指针数组中?
编辑:
一个回答说:
Just because Sprite is a subclass of Drawable, does not mean that
shared_ptr<Sprite>
is a subclass of 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;
}
仅仅因为 Sprite
是 Drawable
的子类,并不意味着 shared_ptr<Sprite>
是 shared_ptr<Drawable>
的子类。
当编译器看到这个时:
engine.lock()->add(sprite);
它根据 overload resolution 规则查找成员函数 add(shared_ptr<sf::Sprite>)
。
尽管 shared_ptr<Sprite>
不是 shared_ptr<Drawable>
的子类,但存在可用的隐式转换,因此它是一个候选者。
但是这样:
template<class T>
void add(std::shared_ptr<T> actor);
为任何类型提供函数的声明,但没有定义。因此,它提供了一个精确匹配,并将由编译器选择。这就是您收到 linker 错误的原因。
解决这个问题的一种方法是使用 std::static_pointer_cast,像这样:
engine.lock()->add(std::static_pointer_cast<Drawable>(sprite));
我也会重新考虑 if/why 你需要上面的模板 - 我看不出它有什么用,除了给你 link 时间错误而不是编译时间错误。
我无法将 sf::Text、sf::Sprite 和 sf::Text 的 shared_ptr 放入 shared_ptr
的数组中
sf::Drawable 是以上所有的母亲 class 并且是抽象的
这是游戏引擎函数:
GameEngine.h
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);
}
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);
}
}
我在 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)
有没有办法将子class的共享指针放入其母class的共享指针数组中?
编辑:
一个回答说:
Just because Sprite is a subclass of Drawable, does not mean that
shared_ptr<Sprite>
is a subclass ofshared_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;
}
仅仅因为 Sprite
是 Drawable
的子类,并不意味着 shared_ptr<Sprite>
是 shared_ptr<Drawable>
的子类。
当编译器看到这个时:
engine.lock()->add(sprite);
它根据 overload resolution 规则查找成员函数 add(shared_ptr<sf::Sprite>)
。
尽管 shared_ptr<Sprite>
不是 shared_ptr<Drawable>
的子类,但存在可用的隐式转换,因此它是一个候选者。
但是这样:
template<class T>
void add(std::shared_ptr<T> actor);
为任何类型提供函数的声明,但没有定义。因此,它提供了一个精确匹配,并将由编译器选择。这就是您收到 linker 错误的原因。
解决这个问题的一种方法是使用 std::static_pointer_cast,像这样:
engine.lock()->add(std::static_pointer_cast<Drawable>(sprite));
我也会重新考虑 if/why 你需要上面的模板 - 我看不出它有什么用,除了给你 link 时间错误而不是编译时间错误。