
- •1. Типи знань і методи їх представлення.
- •2. Парадигми імперативного стилю. Підтримка в мовах програмування. Парадигма процедурності.
- •3. Парадигма модульности (локализации).
- •4. Парадигма атд.
- •5. Парадигма ооп.
- •7. Ефективний доступ до членів класу. Дружні функції та дружні класи.
- •8. Конструкторы и деструкторы.
- •9. Инициализация полей класса. Статические члены класса.
- •10. Наследование классов. Конструкторы базового класса.
- •11. Обмеження доступу до базового класу.
- •12. Множинне наслідування.
- •13. Виртуальные базовые классы.
- •14. Конкретные и абстрактные типы. Виртуальные функции.
- •15. Виртуальные деструкторы и «витруальные» конструкторы. Клонирование.
- •16. Посилання. Ініціалізація, використання, порівняння з покажчиками.
- •17. Перевантаження функцій.
- •18. Перевантаження унарних операцій.
- •19. Перевантаження бінарних операцій.
- •20. Параметризація типів за допомогою шаблонів.
- •21. Параметризація функцій за допомогою шаблонів.
- •22. Перетворення за допомогою конструкторів. Обмеження.
- •23. Перетворення за допомогою перетворюючих функцій.
- •24. Область видимости.
- •25. Пространства имен. Директива using.
- •27. Потоки. Віртуальні операції введення та виведення.
- •29. Узагальнені алгоритми та бібліотека стандартних шаблонів. Ітератори.
17. Перевантаження функцій.
Как правило, разным функциям дают различные имена., но когда функции выполняют концептуально аналогичные задачи для объектов различных типов, может оказаться удобным присвоить им одно и то же имя. Использование одного имени для операции, выполняемой с различными типами, наз перегрузкой. Например +. Эту идею легко распространить на функции, определяемые пользователем. Например: void print (int); //печать целого void print (const char*); //печать символьной строки
С точки зрения компилятора, единственное, что функции имеют общего между собой – это имена. Перегруженные функции предназначены в первую очередь для удобства записи.
Когда вызывается перегруженная функция f, компилятор должен определить, какую из функций с именем f использовать. Нужно использовать функцию с наиболее подходящими аргументами и выдать сообщение об ошибке, если такой не найдено.
Процесс поиска подходящей функции из множества перегруженных заключается в нахождении наилучшего соответствия типов формальных и фактических аргументов. Это осуществляется путем проверки критериев:
1. Точное соответствие типов.
2. Соответствие , достигаемое «продвижением» интегральных типов (bool в int, char в int и т.д.).
3. Соответствие, достигаемое путем стандартных преобразований (int в double, double в int), указателей на произвольные типы в void*, int в insigned int, указателей на производные типы в указатели на базовые.
4. Соответствие за счет многоточий (…) в объявлении функции.
Результат разрешения перегрузки не зависит от порядка объявления функций.
Возвращаемые типы не участвуют в разрешении перегрузки. Функции, объявленные в различных областях видимости, не явл перегруженными.
Заметим, что для любого типа Т: T, const T, T& имеют одно и то же множество инициализирующих значений. Например: void f(int i) void f(int &ri)//Err т.к. принадлежат одному и тому же множеству.
Для любого Т: T& const T& - разные типы.
При наследовании классов одно и то же имя функции в разных классах не перегружается, т.к. имеем дело с разными облястями видимости. Например: void f(int) void f(double) class x1{public: void f(int);}; … class x9:public x8{public: void f(double);} void g(x9*p) {p->f(2)}
18. Перевантаження унарних операцій.
Перегрузка операций. В С++ существует возможность перегрузки стандартных операций + - / * (всего 40). Операции, кот нельзя перегружать: . (выбор члена) .* (выбор члена через указатель на член) :: (разрешение области видимости) ? : # ##
Имя операторной функции начинается с ключевого слова operator, за которым следует сам оператор: operator <<. Операторная функция объявляется и может быть вызвана, как любая другая функция. Использование операторной функции как оператора является просто сокращенной формой ее явного вызова. Например: void f(complex a, complex b) {complex c=a+b; // сокращенная форма complex d=a.operator+(b); //явный вызов }
Ограничения при перегрузке операций: 1. Нельзя перегружать операции для неклассовых типов. Отсюда следует 2 возможности: чтобы операция была членом какого-то класса, созданного пользователем или чтобы по крайней мере один из операндов этой операции был классового типа.
2. При перегрузке нельзя сменять ассоциативность, старшинство, количество операндов.
3. Ограничений на тип, который возвращает перегруженный оператор, нет.
Унарные операции.
Унарный оператор, префиксный или постфиксный, можно определить либо в виде нестатической функции-члена без аргументов, либо в виде функции-не-члена, с одним аргументом. Для любого унарного оператора @ выражение @aa интерпретируется либо как aa.operator@(), либо как operator@(aa). Если определены обе функции, для определения. какую из них использовать, применяется механизм разрешения перегрузки. Для любого постфиксного оператора @ выражение aa@ интерпретируется либо как aa.operator@(int), либо как operator@(aa,int). Если определены обе функции, для определения. какую из них использовать, применяется механизм разрешения перегрузки. Оператор м/б объявлен только с синтаксисом, существующем для него в грамматике. Пример:
class X{ X*operator&();//префиксный унарный оператор & (чей-то адрес); X operator&(X)://бинарный оператор &(и); X operator++(int)//постфиксный инкремент; X operator&(X,X,X)//ошибка – три операнда; X operator/(X); //ошибка – унарный оператор};
//функции –не-члены; X operator-(X);//префиксный унарный -; X operator-(X,X)://бинарный оператор -; X operator--(X&,int)//постфиксный декремент; X operator-();//ошибка – отсутствует операнд; X operator-(X,X,X)//ошибка – три операнда; X operator%(X);