我想知道现代C++11相当于Java的instanceof。我见过这个SO post,但它太旧了,我想知道在C++11中是否有更现代,更好的解决方案?
我希望有一种使用switch结构的可能性,而不必求助于手动枚举类。
class A {
};
class B : public A {
}
class C : public A {
}
on_event(A& obj)
{
switch (obj) {
case A:
case B:
case C:
}
}我的基类没有任何虚方法或函数。我为解析器表示一个表达式树,基类只是一个多态的持有者-就像Haskell/OCaml中的ADT。
发布于 2014-10-12 20:54:59
同样的答案仍然适用,并且在C++中一直是这样的:
if (C * p = dynamic_cast<C *>(&obj))
{
// The type of obj is or is derived from C
}
else
{
// obj is not a C
}这种构造要求A是多态的,即具有虚拟成员函数。
还要注意,这种行为不同于比较typeid(obj) == typeid(C),因为后者测试确切的类型一致性,而动态类型转换以及Java的instanceof只测试目标类型是派生最多的对象的类型的基类。
发布于 2014-10-13 06:34:29
在C++中,普通旧数据(POD)没有运行时类型信息。所描述的所有类都恰好只有1个字节,并且在任何编译器中都有相同的运行时表示,并且具有空基类优化。
因此,你想要的东西是做不到的。
向基类添加一个虚拟析构函数,增加了RTTI和dynamic_cast支持。
将enum或int字段添加到为每个派生类进行不同初始化的基中也是可行的。
另一种选择是创建一个模板函数,并存储指向它的指针,如下所示:
using my_type_id=void(*)();
template<class>void get_my_type_id_helper(){};
template<class T> my_type_id get_my_type_id(){return get_my_type_id_helper<T>;}然后在适当初始化的A中存储my_type_id。这是对RTTI的重新发明,当您想要更多功能时,您将接近C++ RTTI开销。
在C++中,您只需为您所要求的内容付费:您可以请求没有RTTI的类,您确实这样做了,并获得了它。
RTTI是运行时类型信息。POD是普通的旧数据,是一个C++03术语。许多类都不是POD:最简单的方法是添加一个virtual析构函数。C++11具有更细粒度的标准布局和聚合术语。
从技术上讲,RTTI和POD并不是对立的:有些没有RTTI的类不是POD。
请注意,MSVC有不生成RTTI的选项,其积极的Comdat折叠可以打破上面我所做的手动RTTI,在这两种情况下都违反了标准。
发布于 2018-03-15 18:06:00
也许你对我在你提到的旧帖子中发布的答案感兴趣。
https://stackoverflow.com/a/49296405/1266588
该文给出了一种基于C++11、模板元编程和实时传输指令集的不使用dynamic_cast的instanceof实现方案。一个小型的性能测量应用程序表明,如果使用编译器优化,它比dynamic_cast更有效。
https://stackoverflow.com/questions/26325314
复制相似问题