Подтвердить что ты не робот

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

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


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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Если это пользовательский тип с перегруженным унарным 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
}

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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