以下代码解释了问题。填写same_sub_class以检测是否 虚拟基类A的两个指针实际上是同一个具体的 类。
struct A {
...
}:
struct B : public A {
...
}:
struct C : public A {
...
}
bool same_sub_class(A * a1, A * a2){
// Fill this in to return true if a1 and a2 are
// of the same concrete class
}
编辑:
当我查看我的应用程序时,我需要一些与上面略有不同的东西。我需要能够通过type_id对实例进行分组。
FYI。我有一个迷你符号algerbra系统,所以要进行操作,有时候要知道类类型进行排序和重新排列表达式很重要。
所以给出了一个指针向量,用于实例如何通过type_id对它们进行分组。我要么需要能够散列type_id,要么为每个类生成一个唯一的整数。
答案 0 :(得分:18)
如果您可以使用RTTI,
typeid(*a1) == typeid(*a2)
我认为你还需要
#include <typeinfo>
你必须在你的类中有一个虚函数才能存在vtable - 析构函数应该没问题。
<强>更新强>:
我不确定我是否完全理解您对分组的要求(您是否需要某种确定性排序?子类会发生什么?),但您可以尝试使用从value返回的typeid
运算符要么:
typeid(*ptr).name()
typeid(*a1).before(typeid(*a2))
作为排序标准。但是,这在运行之间没有任何确定性。 通常在考虑RTTI时,最好使用精心设计的虚拟函数(例如double dispatch)来查看是否可以更好地完成任何操作。我真的不能说你的情况下是否有一个好的选择,因为我不明白具体细节。
答案 1 :(得分:7)
typeid(*a1) == typeid(*a2)
注意取消引用,这很重要。
答案 2 :(得分:2)
您可以制作自己的类型标识符:
struct A{
...
protected:
enum TypeTag{B_TYPE, C_TYPE};
TypeTag typeTag;
};
然后在子类的构造函数中:
B::B()
: typeTag(TypeTag::B_TYPE)
{
...
}
C::C()
: typeTag(TypeTag::C_TYPE)
{
...
}
答案 3 :(得分:1)
实际上有一个相当简单的答案。但它涉及更清楚地提出问题。
(A)如果我想在unordered_set中存储typeinfo对象,我需要做什么?
typeinfo支持==和name()方法。该名称可用于生成哈希值,==表示相等性
(B)如果我想在ordered_set(std :: set)中存储typeinfo对象,我需要做什么?
typeinfo支持==和before()方法。通过这两种方法的包装,我可以实现一个比较函数的接口,它给我严格的弱排序。
答案 4 :(得分:0)
C ++中有一个名为RTTI(运行时类型信息)的功能,允许您执行此类操作。
运行时类型检查的另一种可能性是创建一个基类,所有类都派生自该基类。在您的基类中包含一个字段,其中包含字符串或数字类型。
答案 5 :(得分:0)
根据您的编译器,可能使用或不使用RTTI的一个技巧如下
const type_info &a1_type_info= typeid(*a1);
const type_info &a2_type_info= typeid(*a2);
return &a1_type_info==&a2_type_info || a1_type_info==a2_type_info;
如果您的编译器按值创建type_info
个实例,则第一次测试失败,但第二次测试失败。如果您的编译器缓存实例,第一个测试将成功(如果它是相同的类型)并且要快得多,因为它只是一个指针比较。如果您的编译器返回不同的实例,因为a1
和a2
来自不同的共享库,它仍然可以工作。