我对运行时检查操作有疑问。
如果一个类包含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
,如果结果为非null,则可以将其添加到列表list
。我很确定有人知道更好的解决方案......
建议更好地实施这个想法也是可以接受的!
答案 0 :(得分:3)
您需要dynamic pointer cast 您的问题是already answered
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);
}
}
答案 1 :(得分:1)
对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很慢。你真的想做一个静态演员(通过暴露一个成员说嘿,我是一个Bi(不推荐,因为它是一个巨大的痛苦,但维护)),或使用多态来选择行为(通过制作b()Ai中的一个函数,并且它在你想让它什么都不做的类中什么都不做。)