Функции C++: амперсанд по сравнению со звездочкой

37
задан mpen 22 March 2009 в 08:15
поделиться

9 ответов

Указатели (т.е. '* ') должны использоваться, где передающий "ПУСТОЙ УКАЗАТЕЛЬ" значим. Например, Вы могли бы использовать ПУСТОЙ УКАЗАТЕЛЬ для представления этого должен быть создан, конкретный объект, или что конкретные меры не должны быть приняты. Или если это когда-нибудь нужно называть от кода НеC++. (например, для использования в общих библиотеках)

, например, функция libc time_t time (time_t *result);

, Если result не является ПУСТЫМ, будет сохранено текущее время. Но если result является ПУСТЫМ, то никакие меры не приняты.

, Если функция, которую Вы пишете, не должна использовать ПУСТОЙ УКАЗАТЕЛЬ в качестве значимого значения затем с помощью ссылок (т.е. '&';) будет, вероятно, менее сбивать с толку - предполагающий, что это - конвенция, которую использует Ваш проект.

40
ответ дан Andrew Edgecombe 23 September 2019 в 20:47
поделиться

Каждый раз, когда возможный я использую ссылки по указателям. Причина этого состоит в том, что намного более трудно завинтить ссылку, чем указатель. Люди могут всегда передавать ПУСТОЙ УКАЗАТЕЛЬ значению указателя, но нет такого эквивалента ссылке.

единственная реальная оборотная сторона является там параметрами ссылки в C++, имеют отсутствие документации сайта вызова. Некоторые люди полагают, что это мешает понимать код (и я соглашаюсь до степени). Я обычно определяю следующее в своем коде и использую его для поддельной документации сайта вызова

#define byref
...
someFunc(byref x);

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

http://blogs.msdn.com/jaredpar/archive/2008/04/03/reference-values-in-c.aspx

12
ответ дан strager 23 September 2019 в 20:47
поделиться

Я думаю, что не согласился бы с @bb и @JaredPar, и я склоняюсь к противоположной стороне забора. После лет попытки поддерживать другой код C++ народов, я часто нахожу проблемы, скрывающиеся в неочевидных побочных эффектах ссылочных аргументов. С C# это очевидно, так как необходимо снабдить префиксом типы споров с 'касательно'/'out', но ссылки потенциально сбивают с толку в C++. Так, мне нравятся указатели, потому что действительно ясно, что что-то возвращается. Если Вам не нравятся точки, C++ не для Вас.

7
ответ дан kenny 23 September 2019 в 20:47
поделиться

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

руководство по стилю C++ Google запреты ссылочные аргументы неконстанты.

6
ответ дан Chad Skeeters 23 September 2019 в 20:47
поделиться

Бывшие силы Вы для вызывания функции с myfunc (& b), таким образом, вызывающая сторона знает, что b будет изменен

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

Моя рекомендация - предпочитает ссылки использования везде, где это возможный (ofcourse, где этому было нужно). В случае, если с аргументом функции - мы извлекаем пользу:
- ссылки не могут быть НУЛЕВЫМИ - это помогает нам избежать, чтобы ошибки и ненужный утверждали или проверили.
- ссылки имеют только одну точку инициализации, и в функции boody Вы всегда знают на том, какая вещь вводила точки параметра.

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

, Но это походит на вопрос о священной войне, у почтительных народов есть другое представление по этому вопросу. Например, Google, вводящий конвенцию в заблуждение, рекомендовал указатели использования в аргументах, которые могли быть изменены и позволены только ссылки константы: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments

Все параметры, переданные ссылкой, должны быть маркированы константа

1
ответ дан bayda 23 September 2019 в 20:47
поделиться

Мне нравится передавать ссылкой, если ПУСТОЙ УКАЗАТЕЛЬ не имеет значения, но я вижу аргументы в пользу обоих. Если Вы осторожны относительно кодирования, Вы могли бы, вероятно, устранить случайное возражение передачи ссылкой путем проверки, что Вы всегда передаете свои переменные ссылкой константы, например:

myfunc( const_cast< const int& >( a ) );

// Alternatively, this approach may require additional handling 
// in the function, but it's cleaner at call point
myfunc( boost::cref( a ) );

Это - много дополнительного кода для небольшого преимущества, все же. Как Kenny указал, C# обратился к этому от противоположного конца (требующий определенной передачи ссылкой), но это не опция для C++ (если, например, Вы не записали свои функции для взятия ссылочной обертки в качестве их параметра, как повышение:: касательно (параметрического усилителя)), например:

void myfunc( const boost::reference_wrapper< int >& a ) { ... }

Решение проблемы указателя более проблематично, хотя... нет никакого времени компиляции способа гарантировать, что указатель допустим, таким образом, Вы заканчиваете или с проблемами времени выполнения для проблем указателя, или с проверками времени выполнения или обоими. Это природа указателей.

Так или иначе, это - просто мое мнение, если это имеет значение.

1
ответ дан Nick 23 September 2019 в 20:47
поделиться

В идеальном мире это сводится, является ли параметр дополнительным выводом. Вы хотите позволить вызывающей стороне передавать ПУСТОЙ УКАЗАТЕЛЬ, если они не заботятся об этом? Тогда используйте указатель. Иначе ссылка является лучшим выбором.

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

0
ответ дан Dan Olson 23 September 2019 в 20:47
поделиться

Одно различие, как было упомянуто прежде, Вы, не может передать нулевую ссылку, но можно передать нулевого указателя.

Другая вещь, также упомянутая уже, когда Вы звоните f(a,b), мог быть беспорядок, если вызывающая сторона не знает, что f мог потенциально изменить значение для b

Однако еще одна проблема, которая является довольно тонкой, но я все еще столкнулся с ним , семантика ссылок.

Указатели передаются значением, но ссылки не.

, Что означает при передаче параметра указателем можно изменить указатель и заставить его указать на что-то еще.

Рассматривают это:

void f1_ptr( type * a )
{
    a = new type(); //no change to passed parameters, you're changing the pointer which was passed by value
}

void f2_ptr( type * a )
{
    *a = some_other_value; //now you're changing the value of the parameter that was passed

   //or, if type is a class or struct:

   a->some_method_that_modifies_object(); //again, changing the parameter that was passed
}

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

void f3_ref( type& a )
{
    a = type(); //the referred variable has also changed
}

//....

type obj = type( params );

f3_ref( obj ); //obj now changed

f1_ptr( &obj ); //obj doesn't change

f2_ptr( &obj ); //obj now changed
0
ответ дан Community 23 September 2019 в 20:47
поделиться

Что-то для замечания при использовании stl функторов легче, если параметр соответствует контейнерному типу значения.

void foo(Bar *);

void frobnicate(vector<Bar *> vecBars)
{
   for_each(vecBars.begin(), 
            vecBars.end(), 
            ptr_fun(&foo));
}

Вышеупомянутый код намного более тверд, если нечто берет Bar&

1
ответ дан 27 November 2019 в 02:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: