2016-10-25 3 views
0

У меня возникли проблемы с положением shared_ptr из sf :: Text, sf :: Sprite и sf :: Text в массив shared_ptr
sf :: Drawable - это материнский класс всех выше и является абстрактным
Вот функция игрового движка:Полиморфизм с помощью умных указателей с использованием шаблонов

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>)" ([email protected]@[email protected]@@[email protected]@[email protected]@[email protected]@@[email protected]@@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 *)" ([email protected]@@[email protected]@[email protected]@@[email protected]@[email protected]@[email protected]@[email protected]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>)" ([email protected]@[email protected]@@[email protected]@[email protected]@[email protected]@@[email protected]@@Z) référencé dans la fonction "public: void __thiscall Rendering::addDrawable(class std::shared_ptr<class sf::Shape>,char const *)" ([email protected]@@[email protected]@[email protected]@@[email protected]@[email protected]) 
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>)" ([email protected]@[email protected]@@[email protected]@[email protected]@[email protected]@@[email protected]@@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)" ([email protected]@@[email protected]@[email protected]@@[email protected]@[email protected]@@@Z) 

Есть ли способ поставить общий указатель подкласса в массив общих указателей его материнский класс?

EDIT:
Ответ сказал, что:

Просто потому, что 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; 
} 
+0

где выполняется реализация add()?он не может найти определение add() –

+0

Скопировано неправильное, извините, отредактировано – Treycos

+0

Я не думаю, что это даже будет работать, потому что ваш шаблонный параметр не совпадает с тем, который объявлен, и вы должны определить функции шаблона в заголовке файл не в cpp –

ответ

2

Просто потому, что Sprite является подклассом Drawable, не означает, что shared_ptr<Sprite> подкласс shared_ptr<Drawable>.

Когда компилятор видит это:

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

это выглядит для функции члена add(shared_ptr<sf::Sprite>) следующего за overload resolution правил.

Хотя 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)); 

Я также хотел бы пересмотреть, если/почему вам нужен шаблон выше - я не вижу, что цель, которая служит, кроме чтобы дать вам ошибки времени соединения, а не ошибки времени компиляции.

+0

@Treyscos see lol –

+0

Ты уничтожил мое имя, котята будут платить за него – Treycos

Смежные вопросы