Использование (void*) в качестве типа идентификатора
-
18-09-2019 - |
Вопрос
В моей программе у меня есть объекты (одного и того же класса), которые должны иметь уникальный идентификатор. Для простоты и производительности я решил использовать адрес объекта в качестве идентификатора. И чтобы поддерживать простые типы, я использую (void*)
как тип для этого идентификатора. В конце концов, у меня есть код, как это:
class MyClass {
public:
typedef void* identity_t;
identity_t id() const { return (void*)this; }
}
Кажется, это работает нормально, но GCC дает мне предупреждение о строгих привязках. Я понимаю, что код был бы плохо, если бы идентификатор использовался для передачи данных. К счастью, это не так, но остается вопрос: влияет ли оптимизации псевдонимов на созданный код? И как избежать предупреждения?
Примечание: я не хочу использовать (char*)
Поскольку это означает, что пользователь может использовать данные для копирования, чего не может!
Решение
Вы нарушаете логическую константу, возвращая объект как изменчивый в методе Const.
Как отмечает Нил, актерский состав не требуется.
class MyClass {
public:
typedef const void* identity_t;
identity_t id() const { return this; }
};
Другие советы
Вы можете попробовать использовать тип uintptr_t
вместо void*
. uintptr_t
это целочисленный тип, который определяется как достаточно большой, чтобы удерживать какое -либо значение указателя. А поскольку это на самом деле не указатель, компилятор не будет помечать проблемы с псевдонимом.
class MyClass {
public:
typedef uintptr_t identity_t;
identity_t id() const { return (identity_t)this; }
}
Попробуйте использовать
return static_cast<void*>(this);
Это должно быть совершенно безопасно, любой указатель должен быть в состоянии поднять на void *
без риска потери.
Я первоначально предложил dynamic_cast(this);
, но, прочитав немного, я думаю, что это не добавляет никакого преимущества, и, поскольку это только RTTI, это не очень хорошее решение в целом.
Кстати, я бы сделал возвращенную стоимость const
, поскольку идентичность объекта не может измениться.
Я не вижу проблем с псевдонимом. Тем не менее, вы отбираете постоянную (так как id
Функция - это const), чем компилятор может быть недоволен. Возможно, было бы лучше использовать const void*
как ваш тип идентификатора.
В качестве альтернативы, подставьте адрес на целочисленный тип, такой как size_t
. Анкет Тогда это больше не указатель, и псевдоним становится не проблема.
Почему бы не использовать тип MyClass *
?
Или тип intptr_t
?