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

Является ли (* i).member менее эффективным, чем i-> member

Имея

struct Person {
   string name;
};

Person* p = ...

Предположим, что никакие операторы не перегружены.


Что более эффективно (если есть)?

(*p).name vs. p->name

Где-то в задней части моей головы я слышу звон колоколов, что оператор разрыва * может создать временную копию объекта; это правда?


В основе этого вопроса лежат такие случаи:

Person& Person::someFunction(){
    ...
    return *this;
}

и я начал задаваться вопросом, изменит ли результат результат на Person*, а последняя строка просто return this будет иметь какое-то значение (в производительности)?

4b9b3361

Ответ 1

Когда вы возвращаете ссылку, это точно так же, как передача указателя, исключение семантики указателя.
Вы возвращаете элемент sizeof(void*), а не sizeof(yourClass).

Итак, когда вы это сделаете:

Person& Person::someFunction(){
    ...
    return *this;
}

Вы возвращаете ссылку, и эта ссылка имеет тот же внутренний размер, что и указатель, поэтому нет разницы во времени выполнения.

То же самое касается использования (*i).name, но в этом случае вы создаете l-value, который затем имеет ту же семантику как ссылка (см. также здесь)

Ответ 2

Нет никакой разницы. Даже в стандарте говорится, что эти два эквивалентны, и если там есть какой-либо компилятор, который не генерирует один и тот же двоичный файл для обеих версий, он плохой.

Ответ 3

Да, его гораздо труднее читать и печатать, поэтому вам гораздо лучше использовать x->y than (*x).y - но помимо эффективности ввода, нет никакой разницы. Компилятору все равно нужно прочитать значение x, а затем добавить смещение в y, независимо от того, используете ли вы одну форму или другую (если не задействованы смешные объекты/классы, которые переопределяют operator-> и operator* соответственно, конечно]

Определенно нет дополнительного объекта, созданного при ссылке (*x). Значение указателя загружается в регистр в процессоре [1]. Что это.

Возврат ссылки обычно более эффективен, поскольку он возвращает указатель (переодетый) объекту, а не делает копию объекта. Для объектов, размер которых больше размера указателя, это обычно выигрыш.

[1] Да, у нас может быть компилятор С++ для процессора, у которого нет регистров. Я знаю, по крайней мере, один процессор от Rank-Xerox, который я видел примерно в 1984 году, у которого нет регистров, он был выделенным процессором LiSP, и он просто имеет стек для объектов LiSP... Но они далеки от общего в сегодняшнем мире. Если кто-то работает над процессором, у которого нет регистров, пожалуйста, не уменьшайте мой ответ просто потому, что я не рассматриваю этот вариант. Я пытаюсь сохранить ответ простым.

Ответ 4

Любой хороший компилятор даст те же результаты. Вы можете ответить на это самостоятельно, скомпилировать оба кода на ассемблер и проверить полученный код.