说B
和C
来自A
。我希望能够测试从A
派生的任何两个类实例是否是同一个类的实例,即A* foo
和A* 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。有没有办法做到这一点?
答案 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