вторник, 21 июня 2011 г.

operator& (address-of)

C++ позволяет переопределять в своих классах ряд операторов, и в их числе — оператор взятия адреса. Попробуем воспользоваться этой возможностью:
struct useless_type {};
class nonaddressable {
  useless_type operator&() const;
};
Пример класса, где переопределен operator& — это CComPtr.

Теперь, если попробовать взять адрес экземпляра класса nonaddressable, то получим ошибку:
nonaddressable* xpe = &x; /* error */
Ошибка может возникнуть по двум причинам: во-первых, в примере оператор взятия адреса приватный, во-вторых — он возвращает экземпляр useless_type, а вовсе не указатель на nonaddressable.

Для разрешения этой ситуации в C++ существует крайне кривой механизм. Можно написать следующий код:
nonaddressable* xp = 
  reinterpret_cast<nonaddressable*>( &reinterpret_cast<char&>( x ) );
Стандарт гарантирует, что это будет работать, но выглядит все равно ужасно. К счастью, в библиотеке Boost существует обертка над этим механизмом — функция boost::addressof, которая учитывает возможные const-volatile. Пользоваться просто:
nonaddressable* xp = boost::addressof(x);

Комментировать в ВКонтакте