3

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

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

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

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

4

5 回答 5

4

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

class MyClass {
public:
    typedef uintptr_t identity_t;
    identity_t id() const { return (identity_t)this; }
}
于 2009-12-08T09:07:26.763 回答
3

您违反了在 const 方法中将对象返回为可变的逻辑 constness。
正如尼尔指出的那样,不需要演员表。

class MyClass {
public:
  typedef const void* identity_t;
  identity_t id() const { return this; }
};
于 2009-12-08T13:03:40.467 回答
2

尝试使用

return static_cast<void*>(this);

这应该是完全安全的,任何指针都应该能够被投射而void *没有丢失的风险。

我最初是建议dynamic_cast(this);的,但是在阅读了一下之后,我认为它没有增加任何优势,而且由于它是 RTTI-only,所以总的来说它不是一个好的解决方案。

顺便说一句,我会返回 value const,因为对象的身份不能改变。

于 2009-12-08T09:04:13.853 回答
1

我看不到任何别名问题。但是,您正在抛弃 constness(因为id函数是 const),编译器可能对此不满意。也许最好const void*用作您的 ID 类型。

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

于 2009-12-08T10:41:25.320 回答
0

为什么不使用类型MyClass *

还是打字intptr_t

于 2009-12-08T09:04:55.233 回答