Когда использовать адресof (x) вместо & amp; x?

Как мне решить, нужно ли мне addressof(x) вместо &x при взятии адреса объекта?


Похоже, вопрос был сбивающим с толку, поэтому уточнение приведено ниже:

addressof очевидно обходит перегруженный адрес оператора. Я уже знаю об этом.

То, что я хочу знать, это:
Как мне узнать, действительно ли это то, чем я хочу заниматься? (Особенно когда внутри шаблона и т. Д.)

Есть ли какое-то «правило», которое помогает мне понять, когда мне нужно addressof вместо &?
В конце концов, они оба возвращают «адрес» объекта, так когда мне использовать какой?

48

Решение

Ты используешь std::addressof когда ты должен. К сожалению, «когда вам нужно» включает любое время, когда вы работаете в коде шаблона и хотите превратить переменную неизвестного типа T или же T& в честный к Богу указатель на память этой переменной.

Поскольку комитет по С ++ по глупости допустил перегрузку ссылочного оператора (с небольшой легитимной целью), пользователь может создать экземпляр вашего шаблона с типом, который вы не можете использовать оператором ссылки для получения фактического указателя. std::addressof это способ обойти пользователей, которые используют эту сомнительную функцию C ++, чтобы делать то, что язык должен был с самого начала работать.

Короче говоря, это исправление библиотеки для языковой глупости. Используйте его в шаблоне кода вместо & если вы хотите убедиться, что пользователи не смогут взломать ваш код. Если вашим пользователям можно доверять, чтобы они не использовали эту непродуманную функцию, тогда вы можете использовать &,

66

Другие решения

Если это пользовательский тип с перегруженным унарным operator&, а вы хотите его адрес, используйте addressof,

Я бы сказал, что вы всегда должны использовать & потому что, как вы говорите, если вы этого не сделаете, это побеждает цель перегрузки. Если не конечно, вы делаете что-то значимое с перегрузкой, в этом случае вам понадобится addressof (вне класса, внутри вы можете просто использовать this), но вы должны быть очень уверены в том, что вы делаете.

Вот еще — если хочешь перегрузить operator& вне класса (вы можете), вы должен использование addressof вернуть адрес, иначе это приведет к бесконечной рекурсии:

struct Class
{
virtual ~Class() {}
int x;
};

void* operator&(const Class& x)
{
//return &x; <---- infinite recursion
return addressof(x) + 4; //I know this isn't safe
//but I also know the intrinsics of my compiler
//and platform to know this will actually return
//the address to the first data member
}

Я знаю, что это не безопасно.

8

Только мое мнение:

Если вы не являетесь частью команды, разрабатывающей класс и его интерфейс, никогда. Лично я никогда не видел веских причин для перегрузки этого оператора. Но если кто-то спроектирует класс там, где это имеет смысл, и предположим, что этот класс предназначен для общественного потребления (то есть класс предназначен не для внутреннего использования только в определенной библиотеке), я буду ожидать, что класс будет работать в обычном коде что естественно ожидает, что & означает «адрес». Если класс, который перегружает оператор, не разработан таким разумным способом, я бы не стал использовать этот класс, точка. Потому что либо этот класс не работает, либо он не предназначен для использования вне библиотеки, частью которой он является.

6

Используйте его, когда вы хотите узнать фактический адрес объекта, а не результат адреса operator& перегрузки.

6

В конце концов, они оба возвращают «адрес» объекта, так когда мне использовать какой?

У вас нет абсолютно никаких гарантий, что перегружен operator& это «адрес» объекта, скорее всего, это не так, иначе автор класса, вероятно, не стал бы перегружать его. Они могли бы перегрузить его, чтобы вернуть другой тип или даже вернуть void если они осознанно пытаются помешать людям принять его адрес.

Если вы хотите указатель на объект, который может быть перегружены & (например, потому что его тип является параметром шаблона, так что вы не знаете), тогда либо используйте std::addressof или документ, что ваш шаблон не поддерживает типы, которые не возвращают реальный адрес объекта как правильный тип.

4
По вопросам рекламы [email protected]