代码之家  ›  专栏  ›  技术社区  ›  PierreBdR

使用(void*)作为标识符的类型

  •  3
  • PierreBdR  · 技术社区  · 16 年前

    在我的程序中,我有(同一类的)对象,这些对象都必须具有唯一的标识符。为了简单和性能,我选择使用对象的地址作为标识符。为了保持类型简单,我使用 (void*) 作为此标识符的类型。最后我得到了这样的代码:

    class MyClass {
    public:
      typedef void* identity_t;
      identity_t id() const { return (void*)this; }
    }
    

    这似乎工作得很好,但gcc给了我一个严格的别名警告。我知道如果ID被用于数据传输,代码会很糟糕。幸运的是,事实并非如此,但问题仍然存在:别名优化会对生成的代码产生影响吗?如何避免警告?

    注:我不愿意使用 (char*) 因为这意味着用户可以使用数据进行复制,而这是不可能的!

    5 回复  |  直到 16 年前
        1
  •  3
  •   Fernando N.    16 年前

    您违反了逻辑常量,将对象作为const方法中的可变对象返回。
    尼尔指出,不需要演员阵容。

    class MyClass {
    public:
      typedef const void* identity_t;
      identity_t id() const { return this; }
    };
    
        2
  •  4
  •   Zach Hirsch    16 年前

    您可以尝试使用该类型 uintptr_t 而不是 void* . uintptr_t 是一个整数类型,定义为足够大以容纳任何指针值。因为它实际上不是指针,所以编译器不会标记任何别名问题。

    class MyClass {
    public:
        typedef uintptr_t identity_t;
        identity_t id() const { return (identity_t)this; }
    }
    
        3
  •  2
  •   unwind    16 年前

    试用使用

    return static_cast<void*>(this);
    

    这应该是完全安全的,任何指针都应该能够 void * 无损失风险。

    我最初建议 dynamic_cast(this); 但是在读了一点之后,我认为它没有任何优势,而且因为它是RTTI,所以一般来说它不是一个好的解决方案。

    顺便说一下,我会把返回值 const ,因为对象的标识不能更改。

        4
  •  1
  •   Stack Overflow is garbage    16 年前

    我看不到任何别名问题。然而,你却抛弃了警察(因为 id 函数是const),编译器可能对此不满意。也许最好用一下 const void* 作为您的ID类型。

    或者,将地址强制转换为整数类型,例如 size_t . 然后它就不再是一个指针,别名也不再是问题了。

        5
  •  0
  •   Didier Trosset    16 年前

    为什么不使用类型 MyClass * ?

    或类型 intptr_t ?