在C++中键入检查

Hom*_*mam 27 c++ casting typechecking

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

Class Base
{
}

Class Child:Base
{
}

Base childObject = new Child();

If (childObject.GetType() == typeof(Child))
{
 // do some code
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

tem*_*def 56

有两种方法可以做到这一点.首先,您可以使用typeid运算符,该运算符返回type_info包含有关对象类型信息的结构.例如:

Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
    /* ... ptr points to a DerivedType ... */
}
Run Code Online (Sandbox Code Playgroud)

请注意,您必须使用typeid(*ptr)而不是typeid(ptr)在这里.如果您使用typeid(ptr),那么您将返回一个type_info对象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 ... */
}
Run Code Online (Sandbox Code Playgroud)

这有一个额外的好处,如果ptr点数类似于某个东西EvenMoreDerivedType,那么强制转换仍会成功,因为EvenMoreDerivedType继承自DerivedType.

最后的想法,你有时会看到这样的代码:

Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
     /* ... points to a DerivedType ... */
}
Run Code Online (Sandbox Code Playgroud)

这在本地范围内derived指向if语句主体的指针,并使用非零值true在C++中求值的事实.我个人认为这更容易阅读,不易出错,但无论如何都要选择最简单的方法.

希望这可以帮助!


Tim*_*Tim 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
Run Code Online (Sandbox Code Playgroud)