在C ++中,我想知道对象的实际类型是来自同一个类,不是同一个类还是派生类。这类似于以下C#代码:
Class Base
{
}
Class Child:Base
{
}
Base childObject = new Child();
If (childObject.GetType() == typeof(Child))
{
// do some code
}
谢谢!
答案 0 :(得分:55)
有两种方法可以做到这一点。首先,您可以使用typeid
运算符,该运算符返回包含有关对象类型信息的type_info
结构。例如:
Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
/* ... ptr points to a DerivedType ... */
}
请注意,您必须在此使用typeid(*ptr)
而不是typeid(ptr)
。如果您使用typeid(ptr)
,那么您将获得type_info
的{{1}}对象,因为指针的类型为Base*
,无论它指向何处。
需要注意的一点是,这将检查Base*
点正好的ptr
是否为DerivedType
。如果ptr
指向从DerivedType
派生的类型的对象(可能是EvenMoreDerivedType
),则此代码将无法正常运行。
检查您是否指向某种类型更健壮的对象的另一种方法是使用dynamic_cast
运算符。 dynamic_cast
在运行时执行检查的类型转换,如果转换成功则生成有效指针,否则返回NULL。例如:
Base* ptr = /* ... */;
DerivedType* derived = dynamic_cast<DerivedType*>(ptr);
if (derived) {
/* ... points to a DerivedType ... */
}
这样做的另一个好处是,如果ptr
指向EvenMoreDerivedType
之类的内容,那么演员方式仍会成功,因为EvenMoreDerivedType
继承自DerivedType
。
最后一点想法,你有时会看到这样的代码:
Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
/* ... points to a DerivedType ... */
}
这是derived
指向if
语句主体的本地范围,并使用非零值在C ++中求值为true
的事实。我个人认为这更容易阅读,更不容易出错,但无论如何都要选择最简单的方法。
希望这有帮助!
答案 1 :(得分:11)
虽然DeadMG的答案是正确的(我已经多次使用过typeid),但我想我会把它扔给后人。从面向对象的视图中执行此操作的“正确”方法是:
Class Base
{
virtual void something() {
// probably a no-op, but maybe some default stuff
}
}
Class Child : public Base
{
virtual void something() {
// do your child-specific code here
}
}
Base* childObject = new Child();
childObject->something(); // does the right thing
答案 2 :(得分:2)
您可以使用typeid()。
if (typeid(childObject) == typeid(ChildType)) {
}
如果返回true,则表示它是子类。