Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
GLAVA_5_Funktsii.doc
Скачиваний:
28
Добавлен:
29.02.2016
Размер:
161.79 Кб
Скачать

Ссылка в качестве возвращаемого значения функции

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

// Пример 5.9. Функция возвращает ссылку.

#include <iostream>

using namespace std;

int x; // глобальная переменная x

int& setx(){return x;}

int main(){

setx() = 555; // присваивание значения x при вызове

// функции, возвращающей ссылку

cout<<"x = "<<x<<endl; // x = 555

}

Здесь функция setx() возвращает ссылку на целое значение, т.е. возвращает псевдоним переменной, стоящей в операторе return этой функции, а это есть ссылка на глобальную переменную x.

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

return 5;

вызывает ошибку компиляции.

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

Встраиваемые функции

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

Но язык программирования С++ позволяет задавать функции, которые не вызываются, а встраиваются в программу в месте её вызова. В результате этого создаётся столько копий встраиваемой функции, сколько раз к ней обращалась вызывающая программа.

Использование встраиваемых функций не связано с механизмом вызова и возврата, следовательно, работают они гораздо быстрее обычных. Однако они способны значительно увеличить объём программного кода. Из-за этого применение встраиваемых функций обычно ограничивается короткими функциями.

Для объявления встраиваемой функции указывают спецификатор inline перед определением функции.

// Пример 5.10. Использование встраиваемой функции для определения

// чётности передаваемого ей аргумента.

#include <iostream>

using namespace std;

inline int even(int x){ return !(x % 2); }

int main(){

int chislo;

cout<<"Vvedi chislo"; cin>>chislo;

if(even(chislo)) cout<<chislo<<" - chetnoe"<<endl;

else cout<<chislo<<" - no chetnoe"<<endl;

system("pause");

}

Спецификатор inline является не командой для компилятора, а только запросом. Поэтому, если компилятор по каким-либо причинам не может встроить функцию, она компилируется как обычная и никаких сообщений об этом на экран не выдаётся.

Некоторые компиляторы не могут сделать функцию встраиваемой, если:

  • функция содержит операторы цикла;

  • функция содержит операторы switch;

  • функция рекурсивная.

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

Перегрузка функций

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

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

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

// Пример 5.11. Использование перегруженной функции суммирования:

// двух целых чисел; трёх целых чисел; двух вещественных чисел.

#include <iostream>

using namespace std;

int sum(int a, int b){ return a + b; }

int sum(int a, int b, int c){return a + b +c;}

float sum(float a, float b){return a + b;}

int main(){

int x, y, z;

float p, q;

cout<<"Vvedi int-chisla x, y, z: ";

cin>>x>>y>>z;

cout<<"Vvedi float-chisla p, q: ";

cin>>p>>q;

cout<<"x + y = "<<sum(x, y)<<endl;

cout<<"x + y + z = "<<sum(x, y, z)<<endl;

cout<<"p + q = "<<sum(p, q)<<endl;

system("pause");

}

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

Существует три жёстких ограничения на возможность перегрузки функций.

  1. Функции не могут быть перегружены, если они отличаются только типом возвращаемого значения.

  2. Функции не могут быть перегружены, если их параметры отличаются только использованием ссылок:

int fun(int par);

int fun(int &par);

  1. Функции не могут быть перегружены, если их параметры отличаются только применением спецификатора const:

int fun(int par);

int fun(const int par);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]