我正在考虑使用typeid()
但我不知道如何询问该类型是否是另一个类的子类(顺便说一下,它是抽象的)
class Base { public: virtual ~Base() {} }; class D1: public Base {}; class D2: public Base {}; int main(int argc,char* argv[]); { D1 d1; D2 d2; Base* x = (argc > 2)?&d1:&d2; if (dynamic_cast(x) == nullptr) { std::cout << "NOT A D2" << std::endl; } if (dynamic_cast (x) == nullptr) { std::cout << "NOT A D1" << std::endl; } }
你真的不应该.如果您的程序需要知道对象是什么类,那通常表明存在设计缺陷.看看您是否可以使用虚拟功能获得所需的行为.此外,有关您尝试做什么的更多信息将有所帮助.
我假设你有这样的情况:
class Base; class A : public Base {...}; class B : public Base {...}; void foo(Base *p) { if(/* p is A */) /* do X */ else /* do Y */ }
如果这是你所拥有的,那么尝试做这样的事情:
class Base { virtual void bar() = 0; }; class A : public Base { void bar() {/* do X */} }; class B : public Base { void bar() {/* do Y */} }; void foo(Base *p) { p->bar(); }
编辑:由于关于这个答案的辩论在这么多年后仍然存在,我想我应该引用一些参考文献.如果你有一个指针或对基类的引用,并且你的代码需要知道对象的派生类,那么它违反了Liskov替换原则.鲍勃叔叔称之为" 面向对象设计的诅咒 ".
你可以这样做dynamic_cast
(至少对于多态类型).
实际上,在第二个想法 - 你不能告诉它是否特定类型与 - dynamic_cast
但你可以告诉它是否是那种类型或其任何子类.
templatebool IsType(const SrcType* src) { return dynamic_cast (src) != nullptr; }
dynamic_cast
可以确定类型是否包含继承层次结构中任何位置的目标类型(是的,它是一个鲜为人知的特性,如果B
继承自A
和C
,它可以A*
直接转换为a C*
).typeid()
可以确定对象的确切类型.但是,这两者都应该非常谨慎地使用.如前所述,您应始终避免动态类型识别,因为它表明存在设计缺陷.(另外,如果你知道对象是为确保目标的类型,你可以做一个垂头丧气了static_cast
.加速提供了一个polymorphic_downcast
会做一个沮丧的用dynamic_cast
和assert
在调试模式下,并在释放模式将只使用一个static_cast
).