- •1.1. _Классика. Общие сведения
- •1.1.3. Элементарные функции ввода-вывода
- •1.2. Функции
- •Void surface(int dl, int VI, int shi);
- •1.3.1. Задание значений аргумента функций по умолчанию
- •1.3.2. Перезагружаемые функции (function overloading)
- •1.3.4. Допускается использование функции с различным количеством аргументов.
- •1.3.6. Дружественные функции (friend)
- •1.3.8. Шаблоны.
- •1.3.9. Виртуальные (virtual) функции
- •1.3.10. Абстрактные классы
- •1.4. Указатели (ссылки). Массивы.
- •Int fprintf ([указатель-На-Входной-Поток], Управляющая-строка, [,Имя-переменной-1, [Имя-переменной-2…]]);
- •Int cprintf (УправляющаяСтрока[,Имя-переменной-1, [Имя-переменной-2…]]);
- •1.6.1 Директива Include
- •1.6.2 Директивы #define и #undef
- •1.6.3 Условные Директивы
- •1.8..Проект (создание проекта классическими средствами языка с)
- •1 .8.1. Классы памяти
- •1.8.3. Проект
- •Раздел 2. Классы
- •31.10.11 Кр Связан с созданием классов и про ооп
- •Лекция 8 от 17.10.2011
- •7.2.2. Динамически присоединенные библиотеки
1.3.4. Допускается использование функции с различным количеством аргументов.
В прототипе пишем первый аргумент обязательно, а следующие могут отсутствовать:
Example(char*per, …)
Т.о. мы начинаем разрабатывать свой класс. Мы не знаем всю его сложность. Но мы считаем, что для него мы будем четко знает первые 2-3 аргумента.
Пусть пользователь задаст верхний левый и нижний правый угол и то, что выводить. В дальнейшем развитии класса уточним остальные аргументы.
1.3.5. Встраиваемые функции используются в языке С в том случае, если в процессе компиляции текст вызываемой функции необходимо вставить в точку вызова. Специализируется ключевым словом inline.
Встраиваемые функции являются аналогом макроопределения препроцессора. Эти функции позволяют:
Отказаться от использования препроцессора. (На прошлой лекции: в языке С – это ввод препроцессора, редактирование программы до того, как она будет откомпилирована… В препроцессоре мы можем давать общее определение константы, которое будут использовать все программисты-разработчики данной фирмы. Появилось желание отказаться от препроцессора, т.к. мы могли использовать разные версии файла stdio.h. Кто-то что меняет. Часть программистов работает с одним, часть с другим. Это приводит к ошибке.)
Встроенные функции позволяют проводить более детализированную трассировку программы в период отладки (debug). В это время можно узнать в какие именно шаги программа работает некорректно, т.е. определить какие были значения переменных. Нужно пошагово определить ошибку. Если тело находится в макросе, то такие данные недоступны.
В отличие от макрокоманд компилятор позволяет производить контроль типов данных и корректность вызова функции.
Я разрабатываю программу в какой-то среде. Мои версии могут меняться от перехода к переходу. И может оказаться так, что фирма разработчик поменяет в моем исходном тексте обращение к какой-то части. Я ссылался на тот алгоритм, который был заложен. Если ее перекомпилировать со средой более новой версии, то могут возникнуть какие-то неполадки. Access 2007 и 1995\2005\2002. Т.е. фирма-разработчик отказывается от того, что было несколько лет назад.
Т.е. нас это не коснется, если использовать встраиваемые функции.
Inline double example (int x) //Вернет число с двойной точностью (плавающая точка)
{ return(x *x *x):
…
Inline void swap (char &a, char &b)
{Char t; t=a; a=b; b=t; }
Если поменять тип данных, то будет более общий пример использования данных функций.
1.3.6. Дружественные функции (friend)
В основе ООП лежит основное правило: внутренние переменные(объекты) должны быть защищены от воздействия извне и только к части из них можно получить доступ через методы данного объекта (инкапсуляция).
Рассмотрим 3 ситуации появления дружественных функций:
При доступе через разработанные методы к внутренним переменным объекта уменьшается эффективность его работы за счет затрат на вызов метода. Не всегда критично, но мешает.
Если классу добавить свой новый метод доступа к внутренним переменным то это нарушит общий интерфейс доступа к объекту данного класса, тем самым разрушая принцип полиморфизма (1 интерфейс – множество методов)
Если потребуется получить прямой доступ к внутренним данным к различным объектам одного и того же класса, то задача значительно будет усложнена.
Для описания дружественной тому или иному классу функции (метода либо класса) в описании объектов предусмотрен спецификатор friend. Если функция дружественна нескольким классам, то надо добавить это описание всем классам, к внутренним данным которых происходит обращение. В языке С без разницы в каком разделе описания класса используется дружественная функция (public – эта функция доступна для внешнего обращения, protected – защищенная часть от прикладного программиста, private).
При разработке класса, сразу говорю, каким именно классам я открываю доступ.
С точки зрения применения механизма инкапсуляции защищенность данных в дружественных функциях сохраняется, т.к. полностью исключается возможность доступа к данным, чтобы объект (класс) об этом не был осведомлен.
// Описание класса А
Class A
{//…
Void z(); //Описание функций z класса А
};
//Описание класса В
Class B
{
//…
Friend void A::Z(); //Описание функции я класса А как дружественной
// классу Вб т.е. из функции я класса А можно
// получить доступ к внутренним переменным класса В
};
// Описание класса С
Class C
{//…friend class A;
//Описание класса А как дружественного классу С,
// все функции класса А будут дружественны классу С и
// из любой функции класса А можно получить доступ к
//внутренним переменным класса С
}
1.3.7. В объявлении функции могут присутствовать два других спецификатора extern и static. Extern – по умолчанию можно получить доступ к функции из других файлов проекта (принято). Static – доступ к функциям только из функции текущей программы, доступ из других внешних модулей не возможен.
Extern “C” { } // Так написано в stdio.h. По умолчанию доступны функции, написанные на яп С.