运行时类型检查
Runtime type checking
我有一个关于运行时检查操作的问题。如果一个类包含从BPAbstract
派生的vector
对象(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
.我很确定有人知道更好的解决方案...
更好地实施这个想法的建议也是可以接受的!
你需要动态指针投射您的问题已经得到解答
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("Aan");}
};
class B : public Bi
{
public:
virtual void a() override {printf("Ban");}
virtual void b() override {printf("Bbn");}
};
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();
}
}
}
但是,动态投射很慢。你真的想做一个静态强制转换(通过公开一个成员说嘿,我是 Bi(不推荐,因为它是一个巨大的痛苦,但维护)),或者使用多态性来选择行为(通过使 b() 成为 AI 中的函数,并让它在您希望它不执行任何操作的类中不执行任何操作)。
相关文章:
- 键入特征以检查类型是否可从流和 MSVC 读取
- 在编译时检查类型是否为 std::basic_string<T> C++
- 检查类型 T 是否具有成员函数 SFINAE 的任何重载
- 检查类型是否为模板的实例化
- 如何检查类型 'T' 是否具有'T(std::initializer_list<U>)'构造函数
- 使用 python 绑定来检查 C++ 类型是否是规范方式的指针、引用等?
- 检查类型的相等性
- C++编译时检查类型
- 使用模板C++检查类型
- 如何检查类型 T 是否在参数包 Ts 中
- 如何使用条件来检查类型名 T 是否是 C++ 中浮点类型的整数类型
- 检查类型是否在 C++ 中定义了 [][]
- 是否有类型特征检查类型之间的包含
- 如何在运行时检查类型
- 使用SFINAE检查类型是否可以绑定到模板模板参数
- 如何检查类型是否是给定类模板的实例化
- 如何在编译时检查类型
- 检查类型是否可以作为 boost::lexical_cast <string>的参数
- 如何检查类型是通过 typedef 定义的还是在模板参数中使用定义的
- 检查类型是否为地图