C++ 在C++;检查基类的两个实例是否属于同一个子类

C++ 在C++;检查基类的两个实例是否属于同一个子类,c++,dynamic-cast,C++,Dynamic Cast,下面的代码解释了这个问题。填写相同的子类以检测是否 指向虚拟基类A的两个指针实际上是相同的具体对象 班级 编辑: 当我查看我的应用程序时,我需要一些与上面稍有不同的东西。我需要能够根据实例的类型\ id对实例进行分组 仅供参考。我有一个迷你符号algerbra系统,所以要进行操作,有时知道类类型对于排序和重新排列表达式很重要 因此,给定一个指针向量,以实例说明如何根据类型\ id对它们进行分组。我需要能够散列类型\ id,或者为每个类生成一个唯一的整数 如果您可以使用RTTI typeid(*a

下面的代码解释了这个问题。填写相同的子类以检测是否 指向虚拟基类A的两个指针实际上是相同的具体对象 班级

编辑:

当我查看我的应用程序时,我需要一些与上面稍有不同的东西。我需要能够根据实例的类型\ id对实例进行分组

仅供参考。我有一个迷你符号algerbra系统,所以要进行操作,有时知道类类型对于排序和重新排列表达式很重要

因此,给定一个指针向量,以实例说明如何根据类型\ id对它们进行分组。我需要能够散列类型\ id,或者为每个类生成一个唯一的整数

如果您可以使用RTTI

typeid(*a1) == typeid(*a2)
我想你也需要

#include <typeinfo>
#包括
类中必须有一个虚函数,这样vtable就存在了——析构函数应该可以

更新

我不确定我是否完全理解您对分组的要求(您是否需要某种确定性排序?子类会发生什么情况?),但您可以尝试使用
typeid
运算符返回的:


  • 散列从
    typeid(*ptr).name()返回的字符串
  • 使用
    typeid(*a1).before(typeid(*a2))
    作为排序标准。不过,这并没有任何决定论
通常在考虑RTTI时,最好看看是否可以使用精心设计的虚拟函数更好地实现这些功能(例如)。不过,我真的不能说在你的情况下是否有好的替代方案,因为我不了解具体情况

typeid(*a1) == typeid(*a2)

请注意取消引用,这很重要。

您可以创建自己的类型标识符:

struct A{
...
protected:
 enum TypeTag{B_TYPE, C_TYPE};
 TypeTag typeTag;
};
然后在子类的构造函数中:

B::B()
: typeTag(TypeTag::B_TYPE)
{
...
}

C::C()
: typeTag(TypeTag::C_TYPE)
{
...
}

< C++ >有一个叫做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
来自不同的共享库,那么它应该仍然可以工作。

实际上有一个相当简单的答案。但这涉及到更清楚地提出问题

(A) 如果我想将typeinfo对象存储在无序的集合中,我需要做什么

typeinfo支持==和name()方法。该名称可用于生成哈希,并==表示相等

(B) 如果我想在一个有序的集合(std::set)中存储typeinfo对象,我需要做什么


typeinfo支持==和before()方法。通过对这两种方法进行一些包装,我可以实现一个比较函数接口,该接口为我提供严格的弱排序

你需要记住也要包括
。但是
必须是多态的,不是吗???@liaK,是的,基类必须至少有一个虚拟函数。@Tim谢谢你。我对问题进行了编辑,以更好地反映我试图解决的问题。事实证明,简单的等式并不是我所需要的!让我们看看:OP必须至少有一个虚拟函数,才能使用
typeid
。添加一个返回type_id为simple
int
的虚拟函数不是最简单的方法吗?typeTag最好是私有的。不是枚举而是变量。@Manoj:我不同意。typeTag在子类构造函数中初始化,因此它不能是基类的私有成员。@Adesit:typeTag必须受到保护。但这种机制并不完美,因为在添加新的子体时,我们需要添加enum的新成员。向敖德萨问好:)我认为这是个坏主意,最好用它RTTI@piotr除非你提供理由,否则简单地说“这么糟糕”是不公平的。我不确定,但我想我的想法是什么rtti是什么样的。一般来说,大多数时候坚持标准是好的,但有时自己实施一些东西会更好。我们不知道海报的具体情况。例如,在Android NDK下不支持RTTI。听起来,您真正需要的是每个类上的静态int来排序。
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;