2015-08-14 6 views
1

код, как:Как работает «передать переменную по ссылке»?

// 'type' here indicates certain variable type, int, char, struct, etc. 
void foo(type &a, type b) {...} 
type a = ...; 
type b = ...; 
type &c = a; 
foo(a, b); 
foo(c, b); 

компилируется без проблем. Но буквально первый параметр foo имеет type&, которая является ссылкой, и foo(c, b) выглядит более последовательным, чем мне foo(a, b), потому что c является ссылкой type& себя, но a только type переменной.

Например сказать void bar(int*) и int *a; int b можно передать только a к bar не b из-за различных типов параметров.

Что такое нижний механизм такой несогласованности при переходе по ссылочному регистру?

+0

Посмотрите на это таким образом, вы можете написать 'type &c = a;', так почему вы ожидаете 'type &a = a;', чтобы не работать в объявлении функции? – user657267

+0

@ user657267 'type &a = a;' - что? –

+0

@MattMcNabb Я пытаюсь сказать, что если вы рассматриваете аргументы функции как просто другое объявление локальной переменной, должно быть очевидно, почему это работает, OP четко понимает, как работает 'type &c = a;', связывая 'a', объявленный ниже' foo 'с аргументом' foo' 'a' ничем не отличается. – user657267

ответ

0

Вы смешиваете объявление переменной с ее использованием.

После:

type a = x; 
type &c = a; 

ситуация точно такая же, как если бы вы написали:

type c = x; 
type &a = c; 

В обоих случаях есть одна переменная, и она имеет два названия, a и c.

Так как C++ 11 есть одно отличие, decltype(a) подберут ссылку как часть типа

При использовании a или c в выражении после этого, он относится к этой переменной.

Если у вас есть void foo(type &p, type q) (измененные имена, чтобы избежать путаницы), а затем, если вы звоните foo(a, b);, то имя p становится другое имя для аргумента a. Существует один объект с двумя именами: a (видимый для вызывающего) и p (видимый в функции).

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

1

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

void foo(type *a, type b) {...} 

type a = ...; 
type b = ...; 
type *c = &a; 
foo(&a, b); 
foo(c, b); 
+1

Ссылка не является адресом памяти. Ссылки могут вообще не требовать хранения (см. [Dcl.ref]/4). Ссылка - это другое имя для объекта. –

+0

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

0

В вашем примере, a имеет типа type и так и b. c имеет тип type&.

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

Ссылки имели обыкновение иметь некоторые отличия, но в наши дни это просто более удобный синтаксис, чем указатели. Использование указателей, ваш пример выглядит следующим образом:

void foo(type *a,type b) {...} 
type a = ...; 
type b = ...; 
type *c = &a; 
foo(&a, b); // the compiler is really doing this for you when you use references 
foo(c, b); 

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

В случае, если это помогает думать об этом лингвистически, ваша функция говорит: «Пожалуйста, дайте ссылку на экземпляр type и копию экземпляра type».

Ваш первый звонок говорит «здесь, возьмите ссылку на этот пример type, и вот копия этого другого примера type».

Ваш второй звонок говорит «здесь, возьмите эту ссылку на экземпляр type, и вот копия этого другого примера type».

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