В чем разница при передаче по ссылке между & и *? - PullRequest
2 голосов
/ 07 декабря 2011

При объявлении функции, в чем разница между параметрами string* и string&?Я знаю, что string s сделает копию строки s и передаст ее по значению, но кажется, что на многих веб-сайтах они ссылаются на string* s и string& s как на передачу по ссылке.Я новичок в C ++, и это единственное, что я не смог понять сам.Заранее спасибо:)

Ответы [ 5 ]

2 голосов
/ 07 декабря 2011

Достойное объяснение здесь:

http://www.cprogramming.com/tutorial/references.html

(Подсказка: это нечто большее, чем «выглядит иначе»)

1 голос
/ 07 декабря 2011

Передача по указателю string* s передает адрес, поэтому s не относится к типу string, это адрес. Если вы разыменовали его, то используется некоторое выражение, включая *s, тогда *s имеет строковый тип.

При передаче по ссылке string& s, s имеет тип string, поэтому разыменование не требуется.

0 голосов
/ 07 декабря 2011

Я считаю параметры указателя весьма полезными двумя способами:

  1. Вызывающий должен передать указатель, который вполне может быть адресом автоматической переменной. Для человека, читающего вызывающий код, становится очевидным, что переменная, адрес которой передается, может измениться.
  2. Указатели могут иметь значение NULL, которое действует как часовой. Ссылки не могут этого сделать. Например, в вашем собственном примере строки & против строки * пустая строка может быть приемлемым значением для переменной и, следовательно, бесполезна в качестве стража. Тем не менее, значение NULL для параметра указателя сообщает вашей функции, что аргумент string * не был установлен вызывающей стороной. Функция, которая получает строку и не имеет возможности определить, установил ли вызывающий объект значение или удовлетворен инициализированным значением по умолчанию.
0 голосов
/ 07 декабря 2011

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

Помимо . против ->:

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

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

0 голосов
/ 07 декабря 2011

Основное отличие состоит в том, как будет вызываться функция. Рассмотрим эти примеры:

void f(string *s)
{}
int main() {
   string s;
   f(&s);
}

и справочная версия:

void f(string &s) { }
int main() {
   string s;
   f(s);
}

Так что вызов функции выглядит иначе ...

`

...