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
Type checking in C++
提问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,则您知道它是子类。

