2014-12-19 7 views
0

У меня есть класс Character, который наследуется от базового класса CollidableObject. CollidableObject имеет, как вы могли догадаться, методы обнаружения коллизий между другими CollidableObject s, такими как CircleCollidableObject и SquareCollidableObject.C++ - передача интеллектуального указателя производного класса

bool CollidableObject::collidesWith(std::shared_ptr<CollidableObject> &pCollidable) 
{ 
    ... 
} 

Я использую это, чтобы запускать другие проверки и в конечном итоге обрабатывать столкновение. В принципе, я хочу, чтобы иметь возможность прокручивать символы в моей игре, пройти через два Character s (что, опять же, наследовать от CollidableObject) и обнаруживать любые столкновения.

void CharacterManager::collisions() 
{ 
    for(std::vector<std::shared_ptr<Character>>::iterator i = mCharacters_.begin(); i != mCharacters_.end(); i++) { 
     for(std::vector<std::shared_ptr<Character>>::iterator j = mCharacters_.begin(); j != mCharacters_.end(); j++) { 
      if(i == j) continue; 
      (*i)->collidesWith(*j); 
    ... 
} 

Я предпочел бы не сделать mCharacters_ вектор в вектор CollidableObjects, если я не должен. Но я не уверен, что это единственный способ.

ответ

3

Можете ли вы переписать интерфейс? Там нет ничего плохого в том:

bool CollidableObject::collidesWith(const CollidableObject* pCollidable) 

Предположительно collidesWith не собирается брать на себя ответственность указателя вы проходите в, так переходящий в сырой указатель отлично.

Сказанное так, shared_ptr<CollidableObject> на самом деле можно построить с shared_ptr<Character>. Поэтому, если вы хотите взять shared_ptr, вам придется взять его на ссылку const вместо ссылки. То есть:

bool CollidableObject::collidesWith(const std::shared_ptr<CollidableObject>& p) 

или просто по значению:

bool CollidableObject::collidesWith(std::shared_ptr<CollidableObject> p) 

См конструктор # 9 из this reference.

И если вы используете std::shared_ptr, вы должны хотя бы использовать auto в своих циклах, чтобы уменьшить многословие. И петля j может начать один пришедшего i, чтобы избежать двойной проверки каждой пары:

for (auto i = mCharacters_.begin(); i != mCharacters_.end(); ++i) { 
    for (auto j = std::next(i); j != mCharacters_.end(); ++j) { 
     (*i)->collidesWith(j->get()); 
     ... 
    } 
} 
+0

Постараюсь это. И я не знал о следующем, поэтому спасибо за это. –

+0

'bool CollidableObject :: collidesWith (const CollidableObject &)' будет моей подписью выбора. – 5gon12eder

+0

Изменение умного указателя на raw приводит к тому, что унаследованные методы и члены недоступны по какой-либо причине. Есть идеи? –

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