С++: реализация равного метода - как убедиться, что данный объект не является тем же самым ссылкой, что и этот?
Рассмотрим следующий фрагмент кода:
bool SomeObject::equal(const SomeObject& rhs) const
{
if (this == &rhs)
{
return true;
}
// check the state
}
Проблема с этим кодом заключается в том, что SomeObject
может переопределить operator&
(или кто-то может добавить его в будущем), что, в свою очередь, может нарушить эту реализацию.
Можно ли проверить, являются ли теги rhs
и *this
одним и тем же объектом, не находясь во власти реализации operator&
?
Ответы
Ответ 1
Если вы хотите получить фактический адрес объекта и игнорировать перегруженные операторы &
, используйте std::addressof
bool SomeObject::equal(const SomeObject& rhs) const
{
if (this == std::addressof(rhs))
{
return true;
}
// check the state
}
Ссылка: http://en.cppreference.com/w/cpp/memory/addressof
Ответ 2
В С++ 11 есть функция std::addressof
, которая должна делать то, что вы хотите.
Если вы хотите реализовать его самостоятельно, вы можете использовать кастинг для другого типа:
(SomeClass*)&reinterpret_cast<char&>(rhs)
Однако я бы не стал беспокоиться; Функция const equals
должна работать нормально для идентичных параметров.
Ответ 3
Что делать, если вы просто полностью исключили это условие? Как часто кто-то собирается сравнивать объект с собой? Если вам, как правило, вообще нужно проверять все данные, то это простое сравнение просто тратит время в среднем случае. Пока ничего плохого не происходит, когда два объекта физически одинаковы (и ваша функция const
, так что вы должны быть в порядке), то какой вред при выполнении небольшой дополнительной работы в редком случае?
Ответ 4
Просто передайте указатель на SomeObject вместо ссылки, так что вам больше не нужен оператор и.
Тогда он хотел бы:
bool SomeObject::equal(const SomeObject* rhs) const
{
if ( this == rhs )
{
return true;
}
//...
}