Объявление ссылочных параметров
В изданной в 1986 г. книге Язык программирования C++ (в которой был впервые описан синтаксис C++) Бьерн Страуструп представил стиль объявления ссылочных параметров, одобренный другими программистами. В соответствии с этим стилем оператор "&" связывается с именем типа, а не с именем переменной. Например, вот как выглядит еще один способ записи прототипа функции swap() .
Нетрудно заметить, что в этом объявлении символ "&" прилегает вплотную к имени типа int , а не к имени переменной х .
Некоторые программисты определяют в таком стиле и указатели, связывая символ "*" с типом, а не с переменной, как в этом примере.
Приведенные объявления отражают желание некоторых программистов иметь в C++ отдельный тип ссылки или указателя. Но дело в том, что подобное связывание символа "&" или "*" с типом (а не с переменной) не распространяется, в соответствии с формальным синтаксисом C++, на весь список переменных, приведенных в объявлении, что может привести к путанице. Например, в следующем объявлении создается один указатель (а не два) на целочисленную переменную.
Здесь b объявляется как целочисленная переменная (а не как указатель на целочисленную переменную), поскольку, как определено синтаксисом C++, используемый в объявлении символ "*" или "&" связывается с конкретной переменной, которой он предшествует, а не с типом, за которым он следует.
|
|
Важно понимать, что для С++‑компилятора абсолютно безразлично, как именно вы напишете объявление: int *р или int* р . Таким образом, если вы предпочитаете связывать символ "*" или "&" с типом, а не переменной, поступайте, как вам удобно. Но, чтобы избежать в дальнейшем каких‑либо недоразумений, в этой книге мы будем связывать символ "*" или "&" с именем переменной, а не с именем типа.
Важно! В языке С ссылки не поддерживаются. Поэтому единственный способ обеспечить в языке С вызов по ссылке состоит в использовании указателей, как было показано выше (см. первую версию функции swap()). Преобразуя С‑код в С++‑код, вам стоит вместо параметров‑указателей использовать, где это возможно, ссылки.
Возврат ссылок
Функция может возвращать ссылку. В программировании на C++ предусмотрено несколько применений для ссылочных значений, возвращаемых функциями. Сейчас мы продемонстрируем только некоторые из них, а другие рассмотрим ниже в этой книге, когда познакомимся с перегрузкой операторов.
Если функция возвращает ссылку, это означает, что она возвращает неявный указатель на значение, передаваемое ею в инструкции return . Этот факт открывает поразительные возможности: функцию, оказывается, можно использовать в левой части инструкции присваивания! Например, рассмотрим следующую простую программу.
|
|
Вот как выглядят результаты выполнения этой программы.
Рассмотрим эту программу подробнее. Судя по прототипу функции f() , она должна возвращать ссылку на double ‑значение. За объявлением функции f() следует объявление глобальной переменной val , которая инициализируется значением 100 . При выполнении следующей инструкции выводится исходное значение переменной val .
После вызова функция f() возвращает ссылку на переменную val . Поскольку функция f() объявлена с "обязательством" вернуть ссылку, при выполнении строки
автоматически возвращается ссылка на глобальную переменную val . Эта ссылка затем используется инструкцией cout для отображения значения val .
При выполнении строки
ссылка на переменную val , возвращенная функцией f() , используется для присвоения значения val переменной newval .
А вот самая интересная строка в программе.
При выполнении этой инструкции присваивания значение переменной val становится равным числу 99,1 . И вот почему: поскольку функция f() возвращает ссылку на переменную val , эта ссылка и является приемником инструкции присваивания. Таким образом, значение 99,1 присваивается переменной val косвенно, через ссылку на нее, которую возвращает функция f() .
|
|
Наконец, при выполнении строки
отображается новое значение переменной val (после того, как ссылка на переменную val будет возвращена в результате вызова функции f() в инструкции cout ).
Приведем еще один пример программы, в которой в качестве значения, возвращаемого функцией, используется ссылка (или значение ссылочного типа).
Эта программа изменяет значения второго и четвертого элементов массива vals . Результаты ее выполнения таковы.
Давайте разберемся, как они были получены. Функция change_it() объявлена как возвращающая ссылку на значение типа double . Говоря более конкретно, она возвращает ссылку на элемент массива vals , который задан ей в качестве параметра i . Таким образом, при выполнении следующей инструкции функции main()
функция change_it() возвращает ссылку на элемент vals[1] . Через эту ссылку элементу vals[1] теперь присваивается значение 5298,23 . Аналогичные события происходят при выполнении и этой инструкции.
|
|
Поскольку функция change_it() возвращает ссылку на конкретный элемент массива vals , ее можно использовать в левой части инструкции для присвоения нового значения соответствующему элементу массива.
Однако, организуя возврат функцией ссылки, необходимо позаботиться о том, чтобы объект, на который она ссылается, не выходил за пределы действующей области видимости. Например, рассмотрим такую функцию.
При завершении функции f() локальная переменная i выйдет за пределы области видимости. Следовательно, ссылка на переменную i , возвращаемая функцией f() , будет неопределенной. В действительности некоторые компиляторы не скомпилируют функцию f() в таком виде, и именно по этой причине. Однако проблема такого рода может быть создана опосредованно, поэтому нужно внимательно отнестись к тому, на какой объект будет возвращать ссылку ваша функция.
Дата добавления: 2018-09-22; просмотров: 261; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!