вторник, 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);

3 комментария:

  1. Если не секрет, где вам понадобилось скрывать адрес класса? Или это так, пост из любви к искусству? :)

    ОтветитьУдалить
  2. Скрыт он оказался в данном примере (случайно). А, вообще, перегрузка operator& может понадобиться для написания прокси классов.

    ОтветитьУдалить
  3. Если нужен конкретный пример, то в CComPtr переопределен operator&.

    ОтветитьУдалить