- •Введение. Принципы объектно-ориентированного программирования
- •Глава 1. Классы и объекты
- •1.1. Операция разрешения области видимости ::
- •1.2. Перечислимый тип
- •1.3. Модификатор const
- •1.4. Новый тип данных – ссылка &
- •Inline определение_функции
- •2. Определение класса. Сокрытие информации.
- •3. Объект.
- •4. Конструкторы и деструкторы
- •4.1.Назначение конструктора
- •4.2. Конструктор копирования
- •X::X(X&); // где X – имя класса
- •4.3. Деструктор
- •5. Неявный указатель this
- •6. Перегрузка операций
- •7. Примеры перегрузки некоторых операций
- •7.1. Перегрузка операции [ ]
- •7.2. Перегрузка операции ()
- •7.6. Перегрузка операции (тип)
- •8. Дружественность
- •Istream
- •10. Массивы объектов.
- •11. Функции- и классы-шаблоны
- •11.1 Функции-шаблоны (родовые функции)
- •11.2 Классы-шаблоны
- •12. Член-данные класса – объекты другого класса: агрегированные классы.
- •Глава 2. Наследование. Полиморфизм
- •1. Базовый и порожденный классы
- •2. Конструкторы порожденного класса
- •3. Стандартные преобразования при наследовании
- •4. Множественное наследование. Виртуальный базовый класс
- •4.1. Прямые базовые классы
- •4.2. Виртуальный базовый класс
- •5. Полиморфизм, раннее и позднее связывание, виртуальные функции
- •5.1 Раннее (статическое) и позднее (динамическое) связывание
- •5.2. Определение виртуальной функции
- •5.3. Чистая виртуальная функция и абстрактный класс
- •5.4. Правила определения виртуальных функций
- •5.5. Механизм позднего связывания
- •6. Библиотека fstream – работа с файлами
- •Глава 3. Библиотека стандартных шаблонов (бсш). Контейнеры
- •1. Контейнер. Структура бсш.
- •2. Контейнер Vector – динамический массив
- •Контейнер list – список
- •4. Контейнер Set – множество
- •Содержание
- •Глава 1. Классы и объекты
- •Глава 2. Наследование. Полиморфизм
- •Глава 3. Библиотека стандартных шаблонов (бсш). Контейнеры
7.6. Перегрузка операции (тип)
Напомним, что операция (тип) используется для преобразования базовых типов данных. Например, если мы хотим вывести код символа char s = ‘*’, то сделать это можно оператором
cout << (int)s;
В С++ есть еще такая форма записи оператора (тип)
тип(выражение).
Например,
float a = 3.76, b = 0.5, c = 1.22, d = 7;
int k = int(a * b – c * d / b);
Пусть задан такой фрагмент программы:
String s1, s2(“Солнце!”); char *str = ”Жарко!”;
Как отреагирует компилятор на следующие присвоения?
s1 = str; // допустимо: преобразование из char* в String выполняет конструктор String(char *) и
// в s1 перепишется строка «Жарко!», поле len = 6.
Итак, преобразование
конструктор(базовый тип)
базовый тип ----------> абстрактный
выполняет конструктор абстрактного класса с аргументом базового типа(если есть).
Теперь рассмотрим присвоение наоборот
str = s2; // ошибка: компилятор не знает, какое поле из объекта s2 требуется переписать в str, то есть,
// что понимается под преобразованием String –> char*
Таким образом, если требуется явно или неявно выполнять преобразование
str = (char *)s2;
то надо определить, что понимается под этим преобразованием.
Перегрузка операции преобразования имеет общий вид
operator тип ( ) {…}
В нашем случае, например, её можно определить следующим образом
String:: operator char *( )
{return line;}
Тогда присвоение
str = s2; // неявное преобразование Sring –> char *
или
str = (char *)s2; // явное преобразование
не вызовет ошибочного сообщения компилятора, и мы получили str = ”Солнце!”.
Можно задать и такое преобразование из типа String в int:
String:: operator int( )
{return len;}
Тогда можно выполнить присвоениe
int k = s2; // k = 7, так как s2 = “Солнце!” и длина строки 7;
Таким образом, преобразование
operator тип
абстрактный класс -------> базовый
задается специальным оператором (тип).
Определим более полезное преобразование из String в int: преобразование числа-строки в форму целого числа.
String :: operator int( )
{int k = 0, i;
for(i = 0; i < len; i++)
k = k * 10 + line[i] - ‘0’;
return k;
}
Пример использования:
String digit(“12345”); int m;
m = digit; // m = 12345, произошло преобразование числа-строки в форму целого числа
Рассмотрим преобразование для класса Complex.
Если в классе Complex определен конструктор вида
Complex(float d = 0) {re = im = d;},
то в функции main() будут справедливы такие действия:
Complex c1, c2(5, 3); float x = 3.3, y;
c1 = x; // Работает конструктор Complex(float ), который определит вещественную и мнимую части
// комплексного числа равными x, то есть с1(3.3 + i * 3.3)
Присвоение
y = c2;
будет ошибочным, так как неизвестно, что надо взять, а что отбросить, когда преобразуем сложный объект в простой.
Поэтому обратное преобразование Complex –> float надо задать, например, таким образом:
Complex:: operator float( ) {return re;}
Тогда оператор
y = c2;
будет верным и y = 5 – вещественная часть c2.
Можно определять преобразование
operator (абстрактный тип2)
абстрактный тип1 ---------> абстрактный тип2
Например, необычное преобразование String –> Complex:
String :: operator Complex( )
{Complex z(len);
return z; // если в классе Complex есть конструктор с одним аргументом
}
Тогда следующий фрагмент кода будет выглядеть совершенно нормально
String s(“Маша ела кашу”); Complex c;
c = s; // c = 13 + i * 13
Задание. Определите столь же необычное, но полезное преобразование Complex –> String.
Особенности перегрузки операции (тип):
Нет аргументов и возвращаемого значения (даже void), так как тип – это и есть возвращаемое значение.
В теле операции обязательно должен быть оператор return со значением, тип которого является типом преобразования.
