2010-03-08 5 views
3

Что фактически передается в вызове ссылкой на функцию?Вызов по ссылке в C++

void foo(int &a,int &b) 

, когда я пишу

foo(p,q) 

что на самом деле передается функции. Это адрес p и q?

+0

Я предполагаю, что вы знаете programtic разницы между ссылкой и указателем, верно? Вы спрашиваете, на что он собственно компилируется? –

+1

@Teller - Ровно – Bruce

+0

@Peter В этом случае, почему бы просто не взглянуть на испускаемый код? – 2010-03-08 19:17:25

ответ

6

Что действительно передается функции, является ссылкой. Именованный параметр b становится синонимом объекта аргумента q.

Как компилятор, вероятно, реализует это, чтобы вызывающий объект помещал адрес q в стек или в регистр перед вызовом, и вызываемый использует это значение для осуществления всех обращений к b. Но это может ввести в заблуждение, чтобы описать это как «фактическое прохождение» указателя, поскольку передача параметров является концепцией на уровне языка C++, и на этом уровне это не та же концепция, что и передача указателя. Например, когда вы передаете указатель, вы можете передать нулевой указатель, но когда вы передаете ссылку, вы не можете (действительно). Поэтому было бы неправильно говорить, что они такие же.

При этом лицо, реализующее компилятор, может описать его как «фактически проходящее указатель», и вы знаете, что они означают. Для сравнения, если переменные char занимают 4-байтовые слоты стека в вызывающем соглашении, они могут сказать, что компилятор «фактически передает int». Так что это зависит от того, что означает «на самом деле».

+1

* «Это зависит от того, что« на самом деле »означает« * ... Политик? – Seth

+0

Больше похоже на педант. –

2

Это действительно получает ссылочный тип - это похоже на адрес, но не совсем. Фактический адрес будет указателем. Ссылки менее эффективны, чем указатели, но, возможно, более безопасны. Wikipedia имеет хорошее описание различий между указателями и ссылками.

0

Способ передачи по справочным работам определяется вашим компилятором. В любом случае они передаются как int&, который является фактическим типом на C++. Попробуйте следующее:

int x = 10; 
int& y = x; 
x = 100; 

Как вы думаете, что это за значение y? Ссылки не являются указателями, а псевдонимами для переменной. Тот же механизм, который ваш компилятор применил к int&, используется для передачи по опорным параметрам.

Учитывая следующую программу:

void byRef(int& x) 
{ 
    return; 
} 

void byVal(int x) 
{ 
    return; 
} 

void byPtr(int * x) 
{ 
    return; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 

    int x = 0; 
    byRef(x); 
    byVal(x); 
    byPtr(&x); 

    return 0; 
} 

MSVC90 Ассамблея генерироваться для byRef и byPtr звонки точно так же, что:

lea eax, [x] 
push eax 
call byRef ;or byPtr 
add esp, 4 
1

Вы передаете ссылку, которая не является указатель, а не адрес, но он похож.

Что такое «точно» ссылка, не задана в камне. Стандарт не диктует механизмы обращения со ссылкой - только последствия их использования. Обычно, они будут реализованы как указатели.

Пример:

int foo(int& a, int& b) { a = b; } 

// Usage 
int x, y; 
foo(x, y); 

Это может генерировать тот же машинный код, как:

int foo(int* a, int* b) { *a = *b; } 

// Usage 
int x, y; 
foo(&x, &y); 

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

Когда вы берете адрес ссылки, вы получаете тот же адрес, что и объект, на который ссылается. Пример:

void foo(int& x) { std::cout << &x << std::endl; } 

int y; 
std::cout << &y << std::endl; 
foo(); // This will print the same as above. 
3

В других ответах упоминается семантическая разница между ссылкой и указателем.

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

вопрос придумают на SO перед: What's the low-level difference between a pointer an a reference?

Смежные вопросы