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 typeid
operator, which returns a type_info
structure 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_info
object 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 ptr
points at is exactlyas DerivedType
. If ptr
is 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_cast
operator. dynamic_cast
performs 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 ptr
points at something like an EvenMoreDerivedType
, the cast will still succeed because EvenMoreDerivedType
inherits 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 derived
pointer to the body of the if
statement and uses the fact that nonzero values evaluate to true
in 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,则您知道它是子类。