- •Базовое ядро языка Элементы программы.
- •Комментарии
- •Инструкция – выражение
- •Инструкция
- •Определение функции
- •Заголовок функции
- •Прототипы функций
- •Аргументы по умолчанию.
- •Перегрузка функций
- •Встраиваемые функции
- •Стек до блока Вошли в блок Вышли из блока
- •Индексирование
- •Int a [100]; одномерный массив
- •Int b [3][5]; двухмерный массив
- •Int c [7][9][2]; трехмерный массив
- •Передача массивов функциям
- •Объявления ссылок и вызовов по ссылке
- •Функции-члены класса
- •Доступ: закрытый и открытый
- •Область видимости класса
- •Оператор разрешения области видимости ::
- •Вложенные классы
- •Статические члены данных
- •Указатель this
- •Функции-члены типа static и const.
- •Изменчивость (mutable)
- •Создание и уничтожение объектов
- •Классы с конструкторами
- •Конструкторы как преобразования
- •Создание динамического стека
- •Классы с деструкторами
- •Пример: динамически размещаемые строки
- •Ad hoc полиморфизм
- •Алгоритм выбора перегруженной функции
- •Перегрузка операторов
- •Перегрузка бинарных операторов
- •Перегрузка операторов присваивания и индексирования
- •Перегруженные операторы ввода-вывода « и »
- •Перегрузка оператора ( ) для индексирования
- •Операторы указателей
- •Указатель на член класса
- •Перегрузка new и delete
- •Наследование.
- •Методология объективно-ориентированного проектирования
- •Виртуальные функции
- •Абстрактные базовые классы
Алгоритм выбора перегруженной функции
1. Использовать строгое соответствие (если возможно).2. Попробовать стандартное повышение типа 3. Попробовать стандартное преобразование типа.
4. Попробовать определяемое пользователем преобразование.
5. Использовать, если возможно, соответствие эллипсису (подразумеваемому аргументу).
Стандартное повышение типа (promotion) лучше, чем остальные стандартные преобразования. Повышение — это преобразования float в double, а также bool, char, short или enum в int. Кроме того, к стандартным преобразованиям относятся преобразования указателей.
Несомненно, строгое соответствие является наилучшим. Для достижения такого соответствия могут использоваться приведения (cast). Компилятор не справится с двусмысленной ситуацией. Поэтому не следует полагаться на тонкие различия в типах и неявные преобразования, которые делают перегруженную функцию неясной. Если вы сомневаетесь, используйте явные преобразования для обеспечения строгого соответствия.
Дружественные функции
Ключевое слово friend (друг) служит спецификатором, уточняющим свойства функции. Оно дает функции-не-члену доступ к скрытым членам класса и предоставляет способ для обхода ограничений сокрытия данных в C++. Однако должна быть веская причина для обхода этих ограничений, поскольку они важны для надежного программирования.
Одна из причин использования дружественных функции состоит в том, что некоторые функции нуждаются в привилегированном доступе к более чем одному классу. Вторая причина в том, что дружественные функции передают все свои аргументы через список аргументов, при этом каждое значение аргумента должно допускать автоматическое преобразование. Преобразования выполняются для переменных класса, передаваемых явно, и особенно полезны в случае перегрузки операторов, как мы увидим в следующем разделе.
Дружественная функция должна быть объявлена внутри объявления класса, по отношению к которому она является дружественной (с которым она дружит). Функция предваряется ключевым словом friend и может встречаться в любой час класса; это не влияет на ее смысл. Мы предпочитаем размещать объявление friend в открытой части класса. Функция-член одного класса может быть дружественной другому классу. В этом случае для указания ее имени в дружественном классе используется оператор разрешения области видимости. То, что все функции-члены одного класса являются дружественными функциями другого класса, может быть указано как friend class имя_класса.
Следующие объявления иллюстрируют синтаксис class tweedledee {
. . . . . friend void alice(); //дружественная функция
int cheshire(); //функция-член
. . . . . };
class tweedledum { . . . . friend int tweedledee::cheshire(); . . . . .
};
class tweedledumber {
. . . . .
friend class tweedledee; //все функции-члены
. . . . . //из tweedledee получают доступ
};
доступ к объектам (в C++ ими являются переменные класса) должен осуществляться через открытые члены. Только функции-члены класса должны иметь доступ к скрытой реализации АТД. Это четкий и строгий принцип разработки. Дружественные функции создают некую двойственность. Они имеют доступ к закрытым членам, не являясь при этом функциями-членами. Их можно использовать для быстрых исправлений в коде, которому необходим доступ к реализации деталей класса. Но такой механизм легко неправильно использовать.