C++ 中的类型检查

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4589226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:51:00  来源:igfitidea点击:

Type checking in C++

c++castingtypechecking

提问by Homam

In C++, I want to know whether the actual type of the object is from the same class, not the same class or a derived one. This is similar to the following C# code:

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

Class Base
{
}

Class Child:Base
{
}

Base childObject = new Child();

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

Thanks!

谢谢!

回答by templatetypedef

There are two ways that you can do this. First, you can use the typeidoperator, which returns a type_infostructure containing information about the type of the object. For example:

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

Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
    /* ... ptr points to a DerivedType ... */
}

Notice that you have to use typeid(*ptr)and not typeid(ptr)here. If you use typeid(ptr), then you'll get back a type_infoobject for Base*, since the pointer has type Base*regardless of what it points at.

请注意,您必须使用typeid(*ptr)而不是typeid(ptr)此处。如果您使用typeid(ptr),那么您将返回一个type_info对象Base*,因为Base*无论指针指向什么,指针都具有类型。

An important point to note is that this will check if what ptrpoints at is exactlyas DerivedType. If ptris pointing at an object of a type derived from DerivedType(maybe an EvenMoreDerivedType), this code will not work correctly.

很重要的一点要注意的是,这将检查什么ptr在点是准确DerivedType。如果ptr指向从DerivedType(可能是EvenMoreDerivedType)派生的类型的对象,则此代码将无法正常工作。

An alternative way of checking whether you are pointing at an object of some type that is a bit more robust is to use the dynamic_castoperator. dynamic_castperforms a checked typecast at runtime that will yield a valid pointer if the cast succeeds and NULL otherwise. For example:

检查您是否指向更健壮的某种类型的对象的另一种方法是使用dynamic_cast运算符。 dynamic_cast在运行时执行检查的类型转换,如果转换成功将产生一个有效的指针,否则为 NULL。例如:

Base* ptr = /* ... */;
DerivedType* derived = dynamic_cast<DerivedType*>(ptr);
if (derived) {
    /* ... points to a DerivedType ... */
}

This has the added advantage that if ptrpoints at something like an EvenMoreDerivedType, the cast will still succeed because EvenMoreDerivedTypeinherits from DerivedType.

这有一个额外的好处,如果ptr指向类似 an 的东西EvenMoreDerivedType,转换仍然会成功,因为EvenMoreDerivedType继承自DerivedType.

As a final thought, you sometimes see code like this:

最后,您有时会看到这样的代码:

Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
     /* ... points to a DerivedType ... */
}

This locally-scopes the derivedpointer to the body of the ifstatement and uses the fact that nonzero values evaluate to truein C++. I personally find this easier to read and less error-prone, but by all means go with what's easiest for you.

这将局部作用域derived指向if语句主体的指针,并使用非零值true在 C++ 中求值为的事实。我个人认为这更易于阅读且不易出错,但无论如何,请选择对您来说最简单的方法。

Hope this helps!

希望这可以帮助!

回答by Tim

While DeadMG's answer is correct (I've used typeid many times), I thought I'd throw this out there for posterity. The "right" way to do this, from an Object-Oriented view is:

虽然 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

回答by Puppy

You can use typeid().

您可以使用 typeid()。

if (typeid(childObject) == typeid(ChildType)) {
}

If this returns true, then you know it's the child class.

如果返回 true,则您知道它是子类。