在C ++中键入检查

时间:2011-01-03 23:04:41

标签: c++ casting typechecking

在C ++中,我想知道对象的实际类型是来自同一个类,不是同一个类还是派生类。这类似于以下C#代码:

Class Base
{
}

Class Child:Base
{
}

Base childObject = new Child();

If (childObject.GetType() == typeof(Child))
{
 // do some code
}

谢谢!

3 个答案:

答案 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,则表示它是子类。