在 C++ 中查找对象的类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/351845/
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-27 14:50:22  来源:igfitidea点击:

Finding the type of an object in C++

c++types

提问by lemnisca

I have a class A and another class that inherits from it, B. I am overriding a function that accepts an object of type A as a parameter, so I have to accept an A. However, I later call functions that only B has, so I want to return false and not proceed if the object passed is not of type B.

我有一个类 A 和另一个继承自它的类 B。我正在覆盖一个接受 A 类型对象作为参数的函数,所以我必须接受一个 A。但是,我后来调用了只有 B 具有的函数,所以如果传递的对象不是 B 类型,我想返回 false 并且不继续。

What is the best way to find out which type the object passed to my function is?

找出传递给我的函数的对象是哪种类型的最佳方法是什么?

回答by yesraaj

dynamic_cast should do the trick

dynamic_cast 应该可以解决问题

TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);

The dynamic_castkeyword casts a datum from one pointer or reference type to another, performing a runtime check to ensure the validity of the cast.

dynamic_cast关键字从一个指针或引用类型转换基准到另一个,执行运行时检查以确保铸造的有效性。

If you attempt to cast to pointer to a type that is not a type of actual object, the result of the cast will be NULL. If you attempt to cast to reference to a type that is not a type of actual object, the cast will throw a bad_castexception.

如果您尝试强制转换为指向不是实际对象类型的类型的指针,则强制转换的结果将为 NULL。如果您尝试强制转换为对不是实际对象类型的类型的引用,则该类型转换将引发bad_cast异常。

Make sure there is at least one virtual function in Base class to make dynamic_cast work.

确保 Base 类中至少有一个虚函数来使 dynamic_cast 工作。

回答by Robocide

Dynamic cast is the best for your description of problem, but I just want to add that you can find the class type with:

动态转换最适合您对问题的描述,但我只想补充一点,您可以通过以下方式找到类类型:

#include <typeinfo>

...
string s = typeid(YourClass).name()

回答by Ana Betts

This is called RTTI, but you almost surely want to reconsider your design here, because finding the type and doing special things based on it makes your code more brittle.

这称为RTTI,但您几乎肯定想在这里重新考虑您的设计,因为找到类型并基于它做一些特殊的事情会使您的代码更加脆弱。

回答by firebush

Just to be complete, I'll build build off of Robocide and point out that typeidcan be used alone without using name():

为了完整起见,我将构建 Robocide 并指出它typeid可以在不使用 name() 的情况下单独使用:

#include <typeinfo>
#include <iostream>

using namespace std;

class A {
public:
    virtual ~A() = default; // We're not polymorphic unless we
                            // have a virtual function.
};
class B : public A { } ;
class C : public A { } ;

int
main(int argc, char* argv[])
{
    B b;
    A& a = b;

    cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl;
    cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl;
    cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl;
    cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl;
    cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl;
}

Output:

输出:

a is B: true
a is C: false
b is B: true
b is A: false
b is C: false

回答by freespace

Probably embed into your objects an ID "tag" and use it to distinguish between objects of class A and objects of class B.

可能会在您的对象中嵌入一个 ID“标签”,并使用它来区分 A 类对象和 B 类对象。

This however shows a flaw in the design. Ideally those methods in B which A doesn't have, should be part of A but left empty, and B overwrites them. This does away with the class-specific code and is more in the spirit of OOP.

然而,这表明设计中存在缺陷。理想情况下,B 中 A 没有的那些方法应该是 A 的一部分但留空,然后 B 覆盖它们。这消除了特定于类的代码,更符合 OOP 的精神。

回答by Joshua

You are looking for dynamic_cast<B*>(pointer)

你正在寻找 dynamic_cast<B*>(pointer)

回答by c64zottel

Because your class is not polymorphic. Try:

因为你的类不是多态的。尝试:

struct BaseClas { int base; virtual ~BaseClas(){} };
class Derived1 : public BaseClas { int derived1; };

Now BaseClasis polymorphic. I changed class to struct because the members of a struct are public by default.

现在BaseClas是多态的。我将 class 更改为 struct ,因为默认情况下结构的成员是公共的。

回答by Naveen

As others indicated you can use dynamic_cast. But generally using dynamic_cast for finding out the type of the derived class you are working upon indicates the bad design. If you are overriding a function that takes pointer of A as the parameter then it should be able to work with the methods/data of class A itself and should not depend on the the data of class B. In your case instead of overriding if you are sure that the method you are writing will work with only class B, then you should write a new method in class B.

正如其他人指出的那样,您可以使用 dynamic_cast。但是通常使用 dynamic_cast 来找出您正在处理的派生类的类型表明设计很糟糕。如果您要覆盖一个将 A 的指针作为参数的函数,那么它应该能够使用 A 类本身的方法/数据,而不应该依赖于 B 类的数据。在您的情况下,如果您确定您正在编写的方法仅适用于 B 类,那么您应该在 B 类中编写一个新方法。

回答by Uri

Your description is a little confusing.

你的描述有点混乱。

Generally speaking, though some C++ implementations have mechanisms for it, you're not supposed to ask about the type. Instead, you are supposed to do a dynamic_cast on the pointer to A. What this will do is that at runtime, the actual contents of the pointer to A will be checked. If you have a B, you'll get your pointer to B. Otherwise, you'll get an exception or null.

一般来说,虽然一些 C++ 实现有它的机制,但你不应该询问类型。相反,您应该对指向 A 的指针执行 dynamic_cast。这将在运行时检查指向 A 的指针的实际内容。如果您有 B,您将获得指向 B 的指针。否则,您将获得异常或空值。

回答by jmucchiello

Use overloaded functions. Does not require dynamic_cast or even RTTI support:

使用重载函数。不需要 dynamic_cast 甚至 RTTI 支持:

class A {};
class B : public A {};

class Foo {
public:
    void Bar(A& a) {
        // do something
    }
    void Bar(B& b) {
        Bar(static_cast<A&>(b));
        // do B specific stuff
    }
};