在我的程序中,我有对象(同一类)必须都有唯一标识符。为了简单和性能,我选择使用对象的地址作为标识符。为了简化类型,我使用(void*)
作为此标识符的类型。最后我有这样的代码:
class MyClass {
public:
typedef void* identity_t;
identity_t id() const { return (void*)this; }
}
这似乎工作正常,但gcc给了我一个严格别名的警告。我知道如果id用于数据传输,代码会很糟糕。幸运的是它不是,但问题仍然存在:别名优化是否会对生成的代码产生影响?以及如何避免警告?
注意:我不愿意使用(char*)
,因为这意味着用户可以使用数据进行复制,但它无法使用!
答案 0 :(得分:4)
您可以尝试使用uintptr_t
类型代替void*
。 uintptr_t
是一个整数类型,定义为足以容纳任何指针值。由于它实际上不是指针,编译器不会标记任何别名问题。
class MyClass {
public:
typedef uintptr_t identity_t;
identity_t id() const { return (identity_t)this; }
}
答案 1 :(得分:3)
你违反了逻辑constness,在const方法中将对象返回为可变对象 正如尼尔指出的那样,不需要演员表。
class MyClass {
public:
typedef const void* identity_t;
identity_t id() const { return this; }
};
答案 2 :(得分:2)
尝试使用
return static_cast<void*>(this);
这应该是完全安全的,任何指针都应该能够转换为void *
而不会有丢失的风险。
我最初建议使用dynamic_cast(this);
,但在阅读之后我认为它没有任何优势,因为它只是RTTI,所以它通常不是一个好的解决方案。
顺便说一句,我会返回值const
,因为对象的身份不能改变。
答案 3 :(得分:1)
我看不到任何别名问题。但是,您正在抛弃constness(因为id
函数是const),编译器可能对此不满意。也许最好使用const void*
作为您的ID类型。
或者,将地址转换为整数类型,例如size_t
。然后它不再是一个指针,并且别名变成一个非问题。
答案 4 :(得分:0)
为什么不使用MyClass *
类型?
或输入intptr_t
?