Javas Class <! - ? - >在C ++中的等价物

时间:2016-06-01 11:28:10

标签: java c++

所以我正在学习C ++并希望编写一个实体组件系统。为此,我需要知道组件将其添加到实体时的类型。在java中我会做这样的事情:

Class<?> someClass = myComponent.class;

我能用C ++做些什么吗?我尝试过typeid(myComponent),但在这种情况下不起作用。

ExtComponent* extended = new ExtComponent();
Component* base = dynamic_cast<Component>(extended);
std::cout << typeid(base).name();

这会返回“类组件”,但我希望在这种情况下返回“类ExtComponent”。我该怎么做。

2 个答案:

答案 0 :(得分:6)

如果我理解正确,你想获得动态类型的对象。 (不是变量本身的类型,而是变量(真正)指的是什么)

Typeid将起作用,因为:

N3337 5.2.8 / 2:

  

当typeid应用于glvalue表达式,其类型为多态类类型(10.3)时,结果引用   到std :: type_info对象,表示最派生对象的类型(1.8)(即动态   glvalue引用[...]

的类型

所以,只需添加一些虚拟功能(可选择虚拟基类),他们就会做你想做的事。

此外,您必须将typeid应用于对象,而不是指针(因为这会为指针返回type_info,而不是对象):

Base *b = new Base;
...
typeid(*b); //not typeid(b)

答案 1 :(得分:2)

处理类型时,必须在编译时解决所有问题。您无法在运行时解决它们。这就是C ++的工作原理。要做一些改变表达式类型的事情,你必须处理模板。

如果我们想创建一个存储各种类型实例的容器,你需要一种方法来记住它是哪种类型。由于模板实例化了一个不同的函数,每个函数都有自己的地址,我们可以用它来为类型生成一个唯一的id:

adding-charts

现在,您可以使用它以安全的方式存储和检索。在这里,我将使用template<typename> void type_id(){} using type_id_t = void(*)(); ,但如果您无法访问C ++ 17功能,则可以将其替换为std::any

boost::any

你走了。您可以像这样试用您的实体:

struct Entity {
    template<typename T>
    void assign(T component) {
        components[type_id<T>] = component;
    }

    template<typename T>
    T& retrieve() {
        return std::any_cast<T>(components[type_id<T>]);
    }

private:
    std::map<type_id_t, std::any> components;
};

这是实体的垃圾和简单实现。通常,您尝试将实体和组件保存到内存中,并使用实体管理器管理它们的生命周期。