Функции C ++, принимающие значения, где они должны брать ссылки - PullRequest
1 голос
/ 24 февраля 2010

Я только изучаю c ++ и, исходя из c, некоторые вызовы функций, которые я вижу в книге, смущают меня:

char a;
cin.get(a);

В C это не могло бы работать, если бы вы это сделали, не было бы никакого способа получить выходные данные, потому что вы передаете по значению, а не по ссылке, почему это работает в c ++? Являются ли ссылки и разыменования неявными (компилятор знает, что для cin.get нужен указатель, поэтому на него ссылаются)?

Ответы [ 4 ]

11 голосов
/ 24 февраля 2010

C ++

Это будет работать в C ++, потому что сигнатура функции для get(), вероятно, такая:

void get(char& a); // pass-by-reference

Символ & после char обозначает для компилятора, чем когда вы передаете значение char, он должен передать ссылку в char вместо создания копии это.

По сути это означает, что любые изменения, внесенные в get(), будут отражены в значении a вне метода.

Если подпись функции для get() была такой:

void get(char a); // pass-by-value

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

C

Причина, по которой это не сработает в C, заключается в том, что C имеет только значение передачи . Единственный способ эмулировать поведение pass-by-reference в C - это передать его указатель по значению, а затем отменить ссылку на значение указателя (таким образом получая доступ к той же ячейке памяти) при изменении значения внутри метода :

void get(char* a)
{
    *a = 'g';
}

int main(int argc, char* argv[])
{
    char a = 'f';
    get(&a);
    printf("%c\n", a);

    return 0;
}

Запуск этой программы выдаст:

g
4 голосов
/ 24 февраля 2010

Типы ссылок работают так (передача по ссылке, а не по значению). Это похоже на передачу указателя (проход за указателем) в C, но с более приятным синтаксисом и большей безопасностью (проверки во время компиляции). Реализация проходит по указателю внутри.

1 голос
/ 24 февраля 2010

Вот почему некоторые программисты на C ++ не любят использовать такие ссылки.
Это похоже на аргумент функции - вы не можете понять из синтаксиса, является ли «а» измененным или нет.

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

1 голос
/ 24 февраля 2010

C ++ позволяет передавать по ссылке (обратите внимание на &, что означает, что ссылка используется):

void foo(char& bar) {
    bar = 42;
}

int main() {
    char a;
    foo(a);
    // a == 42 here
}
...