代码之家  ›  专栏  ›  技术社区  ›  Jon Purdy

无RTTI的类型相等性测试

  •  1
  • Jon Purdy  · 技术社区  · 14 年前

    B C 源于 A . 我希望能够测试类的任何两个实例是否派生自 是同一类的实例,也就是说,是否 A* foo A* bar 都指向 实例,不使用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 从派生类中自动找到代码 ,这样不是所有派生类都必须重复这个习语。同样,我强烈希望不要使用RTTI。有什么办法吗?

    注: 我看过最近的问题 [1] [2] ,这不是副本。那些海报想测试 内容 它们的派生类;我只想测试 恒等式 .

    4 回复  |  直到 14 年前
        1
  •  3
  •   Tronic    14 年前

    你应该使用RTTI而不是重新设计轮子。

    如果坚持不使用rtti,可以使用crtp和函数局部静态变量,以避免将函数写入每个派生类。根据我为维基百科编写的示例代码改编: http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Polymorphic_copy_construction

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

        2
  •  2
  •   Dominic Cooney    14 年前

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

    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 返回最派生的类型。

        3
  •  0
  •   Naveen    14 年前

    你可以坐头等舱 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)
        {
        }
    };
    
        4
  •  -1
  •   jojo    14 年前

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