- •1)Краткий обзор основных парадигм программирования
- •Основные принципы ооп
- •Абстрактные типы данных
- •Синтаксис описания класса
- •Управление доступом к членам класса
- •Манипуляции с состоянием объекта
- •Класс как область видимости
- •Объявление и определение методов класса. Спецификатор inline
- •Указатель на член класса
- •Указатель this
- •Конструкторы и деструкторы
- •Конструктор умолчания
- •Конструктор преобразования и конструкторы с двумя и более параметрами
- •Конструктор копирования
- •Порядок вызова конструкторов и деструкторов
- •Статические члены класса
- •Константные члены класса. Модификатор const
- •Друзья классов
- •Статический полиморфизм
- •Перегрузка бинарных операций
- •Перегрузка унарных операций
- •Перегрузка функций
- •Виды отношений между классами
- •Одиночное наследование
- •Правила наследования
- •Преобразования указателей.
- •Правила видимости при наследовании.
- •Закрытое (private) наследование
- •Перекрытие имен
- •Динамический полиморфизм, механизм виртуальных функций
- •Реализация виртуальных функций
- •Абстрактные классы. Чистые виртуальные функции
- •12. Средства обработки ошибок, исключения и обработка исклю-чений
- •Правила выбора обработчика исключения
Перегрузка функций
Имеется возможность описывать разные алгоритмы для одного и того же идентификатора функции при разных количествах и наборах типов входных па-раметров. Такое описание разных алгоритмов в одной зоне описания (класс, пространство имен) называется перегрузкой функций (если описание разных алгоритмов для одного и того же имени осуществляется в разных зонах, то гово-
рят о перекрытии).
При вызове функции для выбора подходящей перегруженной функции вы-полняется следующий алгоритм:
Алгоритм поиска оптимально отождествляемой функции
Отбираются функции с необходимым количеством формальных пара-метров.
Примечание. Возможно описание функции с переменным числом параметров . Для этого используются символы ‘. . .’ в конце списка формальных параметров, обо-значающих произвольное количество дополнительных неименованных параметров, типы которых будут определяться непосредственно при вызове функции. Пример про-тотипа функции с переменным числом параметров:
void f1(int i1, . . .);
В этом случае внутри функции необходимо иметь специальные средства получения значений таких дополнительных параметров, не имеющих собственных имен. При об-работке списка формальных параметров компилятор не имеет информации, необходи-
мой для выполнения стандартной проверки и преобразования типов неименованных параметров. Поэтому средства получения таких параметров могут использовать только информацию, недоступную компилятору. Для облегчения работы с этими параметрами в файле stdarg.h стандартной библиотеки имеются описания структуры va_list и функций: va_start(), va_arg(), va_end(). Описания, содержащиеся в библио-течном файле <cstdarg>, становятся доступными после его подключения директивой препроцессора #include <cstdarg>.
Функции с переменным числом параметров рекомендуется использовать в ис-ключительных случаях, когда типы параметров действительно неизвестны. В большин-стве случаев можно использовать функции с аргументами по умолчанию или функцией с двумя параметрами следующего вида: первый параметр – целое число, равное количе-ству содержательных параметров, второй аргумент – указатель на массив указателей на фактические параметры. Такой метод используется при передаче списка строковых па-раметров из командной строки вызова программы на исполнение:
int main(int argc, char* argv[])
Здесь args – количество строковых параметров в командной строке вызова про-граммы на исполнение, включая идентификатор программы.
Для каждого фактического параметра вызова функции строится множе-ство функций, оптимально отождествляемых по этому параметру (best matching)
Находится пересечение этих множеств
Если полученное множество состоит из одной функции, то вызов раз-решим. Если множество пусто или содержит более одной функции, то генерируется сообщение об ошибке.
Пример:
class x{
. . .
public:
x(int i1){. . . }
. . .
};
class y{. . .};
void f(x x1, int i1){. . .} void f(x x1, double d1){. . .} void f(y y1, double d1){. . .}
void g(){. . . f(1,1) . . .} // вызов первой реализации f(x, int)
Пример:
class x{
. . .
public:
x(int i1){. . . }
. . .
};
void f(x x1, int i1){. . .} void f(int i1, x x1){. . .}
void g(){. . . f(1,1) . . .} // ошибка: пересечение
// множеств – пусто.
