在没有RTTI的情况下测试类型相等

时间:2010-02-11 06:09:14

标签: c++ equality rtti

BC来自A。我希望能够测试从A派生的任何两个类实例是否是同一个类的实例,即A* fooA* bar是否都指向B实例,不使用RTTI。我目前的解决方案是这样的:

class A {
protected:

    typedef uintptr_t Code;
    virtual Code code() const = 0;

}; // class A


class B : public A {
protected:

    virtual Code code() const { return Code(&identity); }

private:

    static int identity;

}; // class B


class C : public A {
protected:

    virtual Code code() const { return Code(&identity); }

private:

    static int identity;

}; // class C

使用此方法,operator==可以简单地测试first.code() == second.code()。我想从派生类中删除文字identity并让A自动找到代码,这样就不是所有的派生类都必须重复这个习惯用法。同样,我强烈不想使用RTTI。有没有办法做到这一点?

注意:我见过最近的问题[1][2],这不是重复的问题。那些海报想要测试其派生类的内容;我只是想测试身份

4 个答案:

答案 0 :(得分:3)

你应该只使用RTTI而不是重新发明轮子。

如果您坚持不使用RTTI,则可以使用CRTP和函数本地静态变量来避免必须将函数写入每个派生类。改编自我为维基百科撰写的示例代码:http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Polymorphic_copy_construction

另一种选择是读取vtable指针(通过this和指针算术),但这将取决于编译器和平台,因此它不可移植。

答案 1 :(得分:2)

你的想法是正确的;也许你可以用模板消除一些样板:

class TypeTagged {
public:
  virtual Code code() const = 0;
}

template <class T>
class TypeTaggedImpl: public virtual TypeTagged {
public:
  virtual Code code() const { return Code(&id); }
private:
  static int id;
}

然后你的客户端类需要像这样声明:

class A: public TypeTaggedImpl<A> { ... }

class B: public A, public TypeTaggedImpl<B> { ... }

TypeTagged的不同实例表示类型具有不同的id字段,因此具有不同的ID;虚拟基类型意味着返回最派生类型的code

答案 2 :(得分:0)

您可以让Base类将id作为构造函数参数,并在基类本身中实现identity()函数。然后,不需要在派生类中重复代码。在派生类构造函数中,您可以执行类似derived::derived(): base(0)示例代码:

的操作
class A
{
public:
    A(int n) : m_id(n)
    {
    }
    virtual ~A(){}

    virtual int id() const 
    {
        return m_id;
    }

private:
    int m_id;
};

class B : public A
{
public:
    B() : A(0)
    {
    }
};

答案 3 :(得分:-1)

您可以将两个宏__FILE__ __LINE__用作代码
这样可以避免碰撞问题 您可以将此值映射到int