Указатель vs. Снабди ссылками

Первоначальный автор вопроса

https://stackoverflow.com / questions / 114180/pointer-vs-reference

Джек Реза https://stackoverflow.com/users/20349/jack-reza

Что было бы наиболее практическим во время перемещения первоначальной переменной в функцию, чтобы работать с нею из-за:

unsigned long x = 4;

void func1(unsigned long& val) {
     val = 5;            
}
func1(x);

или из-за:

unsigned long x = 4;

void func2(unsigned long* val) {
     *val = 5;
}
func2(&x);

Какой-то разум есть, чтобы выбирать один на другом?

3
задан 23.05.2017, 15:39
3 ответа

Указатели и ссылки - концептуально то же самое, хотя существуют тонкие различия между ними. Самая достопримечательная из них (и вероятно, наименее важная, хотя да удобнее и читабельнее), он состоит в том, что ссылки не нуждаются синтаксиса в стреле -> что нуждаются в указателях, чтобы соглашаться на членов (в случае, если объект (class) или я регистрирую (struct) на него указали), или оператор доступа *, но они используют Ваше собственное имя, чтобы соглашаться на стоимость, и оператор ., тот, который был бы использован тем же объектом, чтобы соглашаться на членов.

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

Этот код относительно сложный, для которого в действительности он хочет быть полученным:

unsigned long x = 4;

void func2(unsigned long* val) {
     *val = 5;
}
func2(&x);

В то время как версия со ссылками гораздо читабельнее:

unsigned long x = 4;

void func1(unsigned long& val) {
     val = 5;            
}
func1(x);

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

  • Ссылки не могут инициализироваться в NULL или nullptr. Более того, даже они не могут быть созданы, не инициализировались раньше. И однажды инициализировавшие, не возможно менять объект или стоимость, на которые они указывают.

  • Не возможно использовать арифметику указателей со ссылкой. Например, не возможно пробегать вектор объектов со ссылкой, так как не возможно менять объект, на который он указывает однажды созданная.

Так, следующий код не может быть написанным ссылкой:

Persona * p = personas;

for(; ( p - personas ) < MaxPersonas; ++p) {
    cout << p->getNombre() << endl;
}

Отсюда "правила из золота", появившиеся в другом ответе: если ты нуждаешься в том, чтобы указать на более одного объекта, или ты нуждаешься в том, чтобы показать, что он ни во что не записывается (стоимость NULL), или нуждаешься в том, чтобы использовать арифметику указателей, тогда не можешь использовать ссылки. Когда ты сможешь использовать их, однако, не сомневайся в том, чтобы делать это, так как они гораздо читабельнее благодаря Вашему синтаксису.

Я надеюсь помочь тебе.

7
ответ дан 01.12.2019, 08:17

первоначальный Автор

Нильс Пипенбринк https://stackoverflow.com / users / 15955/nils-pipenbrinck

Мое правило из золота:

Использовал указатели, если Вы хотите сделать aritmГ©tica указателей с ними (например, увеличивая ее direcciГіn с указателя до шага в travГ©s массива), или если когда-нибудь он должен перемещать NULL-Указатель.

Использовать ты снабжаешь ссылками по-другому.

2
ответ дан 01.12.2019, 08:17
  • 1
    #191; Цюй и # 233; перемести, если funci и # 243; n, что получает переменную, должно использовать другой funci и # 243; n, что требует указателя в эту переменную? Например я перемещаю переменную long, который я захочу написать в файле с fwrite (puntero_a_var, sizeof (long), 1, file), который нуждается в указателе в переменную. и #191; Он был должен перемещать переменную как указатель или как ссылка? – Jose Antonio Reinstate Monica 05.12.2015, 12:37
  • 2
    я верю в то, что понимаю Ваш вопрос, если Вы создаете функцию (смотреть ответ @Baltasarq " очень хорошая из-за cierto"), и основываясь на ней прими решение создать функцию давайте говорить главный, что потребовал одной variable_long& но внутри этой функции требуют одной varible_long*, так как Вы можете использовать suFuncion (& variable_long), чтобы звонить в функцию (variable_long*...) – Angel Angel 06.12.2015, 03:54

Важное различие состоит в том, что указатели могут сравниваться с NULL и ссылками не.

Хотя эти вещи всегда субъективные одно из более получающих правил стиля - правило Google (https://google.github.io/styleguide/cppguide.html#Reference_Arguments) в той, которую рекомендует перемещать аргументы из-за ссылки только для стоимости, которая никогда не меняется (const). Если аргументы могут меняться, они рекомендуют перемещать их как указатели, чтобы мочь, между другими вещами, подтверждать, что это не NULL. Более общей формы они говорят, что у ссылок есть поведение указателей но синтаксис стоимости то, что способствует тому, чтобы они были смущенными.

2
ответ дан 01.12.2019, 08:17