1

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

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

4 回答 4

3

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

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

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

于 2010-02-11T06:31:29.947 回答
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返回最多派生类型。

于 2010-02-11T06:44:26.137 回答
0

您可以将基类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)
    {
    }
};
于 2010-02-11T06:14:15.647 回答
-1

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

于 2010-02-11T06:14:41.087 回答