У меня есть вопрос о проверке во время выполнения.
Если класс содержит vector
объектов, происходящих из BPAbstract
(BPAbstract
будучи чисто виртуальным) вроде:
typedef std::shared_ptr<BPAbstract> Ptr;
std::vector<BPAbstract::Ptr> objects_;
Теперь давайте скажем, что я хочу сгруппировать объекты определенного типа в vector
,
template<class T>
void
GetObjectsByType( std::vector<typename T::Ptr> list ) const
{
for( BPAbstract::Ptr i : objects_ )
{
// ???? ....
}
}
Какова будет лучшая реализация? Одним из решений будет попытка разыграть i
в тип T
и если результат не нулевой, то я могу добавить его в список list
, Я уверен, что кто-то знает лучшее решение …
Предложение лучшей реализации идеи также будет приемлемым!
Тебе нужно динамическое приведение указателя
Ваш вопрос уже ответил
template<class T>
void
GetObjectsByType( std::vector<typename T::Ptr> list ) const
{
for( BPAbstract::Ptr i : objects_ )
{
T::Ptr candidate = std::dynamic_pointer_cast<T>(i);
if (candidate)
list.add(candidate);
}
}
Извините за синтаксис C ++ 0X, но вариант динамического приведения:
class Ai
{
public:
virtual void a() = 0;
};
class Bi : public Ai
{
public:
virtual void b() = 0;
};
class A : public Ai
{
public:
virtual void a() override {printf("Aa\n");}
};
class B : public Bi
{
public:
virtual void a() override {printf("Ba\n");}
virtual void b() override {printf("Bb\n");}
};int _tmain(int argc, _TCHAR* argv[])
{
typedef std::shared_ptr<Ai> Ptr;
std::vector<Ptr> list;
list.push_back(Ptr(new A()));
list.push_back(Ptr(new B()));
for (auto i = list.begin(); i != list.end(); ++i)
{
(*i)->a();
auto b = std::dynamic_pointer_cast<Bi>(*i);
if (b)
{
b->b();
}
//or, equally valid without additional shared_ptr overhead:
auto bptr = dynamic_cast<Bi*>(i->get());
if (bptr )
{
bptr->b();
}
}
}
Однако Dynamic Cast работает медленно. Вы бы действительно хотели сделать статическое приведение (выставив члена, который говорит: «Эй, я Би (не рекомендуется, так как это огромная боль, но поддерживать))», или использовать полиморфизм для выбора поведения (делая b () функция в Ai, и пусть она ничего не делает в классах, для которых вы хотите, чтобы она ничего не делала).