Делает ли разыменование указатель его копию? - PullRequest
35 голосов
/ 14 декабря 2010

Создает ли копия объекта разыменование указателя и передачу его функции, которая получает аргумент по ссылке?

Ответы [ 4 ]

31 голосов
/ 14 декабря 2010

В этом случае значение в указателе копируется (хотя это не обязательно так, поскольку оптимизатор может оптимизировать его).

int val = *pPtr;

В этом случае, однако, копия не будет создана:

int& rVal = *pPtr;

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

То же самое, очевидно, относится и к параметрам функции.

7 голосов
/ 14 декабря 2010

В простом случае нет. Однако есть более сложные случаи:

void foo(float const& arg);
int * p = new int(7);
foo(*p);

Здесь создается временный объект, поскольку тип разыменованного указателя (int) не соответствует базовому типу параметра функции (float). Последовательность преобразования существует, и преобразованный временный объект может быть связан с arg, так как это постоянная ссылка.

4 голосов
/ 14 декабря 2010

Надеюсь, что нет: если вызываемая функция примет аргумент по значению.

Кроме того, это ожидаемое поведение ссылки:

void inc(int &i) { ++i; }

int main()
{
    int i = 0;
    int *j = &i;
    inc(*j);
    std::cout << i << std::endl;
}

Ожидается, что этот код напечатает 1 , поскольку inc принимает аргумент в качестве ссылки. Если бы копия была сделана при inc вызове, код напечатал бы 0.

3 голосов
/ 14 декабря 2010

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

...