Использование (void*) в качестве типа идентификатора

StackOverflow https://stackoverflow.com/questions/1865652

  •  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?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top