- •Алгоритм.
- •Множественный выбор switch.
- •Оператор do … while ( с постусловием ).
- •Do оператор ;
- •Оператор цикла for.
- •Использование операторов break и continue в циклах.
- •Функции ввода-вывода.
- •Общий вид программы.
- •Вложенные циклы.
- •Адреса и указатели.
- •Массивы.
- •Int a[10] ; // целочисленный вектор из 10 элементов.
- •Векторы.
- •Сортировка вектора.
- •Матрицы.
- •Строки.
- •Подпрограммы.
- •Директива препроцессора #define .
- •Области видимости.
- •Классы памяти.
- •Рекурсия.
- •Подготовка к зачету.
- •Структуры.
- •Int ball [4] ; // описание третьего поля – оценки.
- •Очередь.
- •Линейные списки.
- •Деревья.
- •Int n, k ; // ее размерности
- •Void print ( void ) // печать матрицы
- •Определение методов вне класса.
- •Частные и общие данные.
- •Конструктор.
- •Перегрузка операторов.
- •Неявный указатель *this.
- •Дружественные функции.
- •Класс множество.
- •Наследование.
- •Объекто-ориентированное программирование.
- •Список вопросов к экзамену.
- •Литература.
Перегрузка операторов.
Тип переменной определяет ее внутреннее представление и набор операций над ней. Вспомните, что операция деления для целых и вещественных переменных производится по разному.
Вернемся к классу матриц, перегрузим для него операцию присваивания, в main() вызов этой функции будет выглядеть так С = А ; где А и С матрицы.
void operator = ( cmatr &a)
{ for ( int i=0 ; i<n ; i++)
for ( int j=0 ;j<=k ; j++ )
m[i][j] = a.m [i][j] ;
}
Адрес матрицы, стоящей справа пересылается в подпрограмму через параметры, а матрица, стоящая слева считается текущим объектом и видна из подпрограммы.
Перегрузка оператора состоит в изменение его смысла, только для операндов описанных в данном классе, для всех остальных смысл не изменяется.
x = t ; // для целых
C = A ; // для матриц
Написать тоже действие можно и через обычную функцию, но это будет не наглядно, например:
C.pr(A) ; вместо C = A ;
Перегрузка операторов упрощает понимание программ.
Описание функции, перегружающей оператор, выглядит так:
Тип_результата имя_класса::operator знак_оператора ( параметры)
{ тело функции }
С++ позволяет перегружать все операторы кроме:
Знак оператора |
Назначение |
Пример |
. |
Выбор элемента |
a.m[i] |
.* |
указатель |
(*pp).next |
:: |
Глобальное разрешение |
class::cvec |
?: |
Условный оператор сравнения |
c=( a>b) ? a : b |
# |
Описание библиотеки |
#include<math.h> |
Рассмотрим еще один пример перегрузки оператора для класса строка: задана строка выбросить из нее любой заданный символ. Создавать весь класс мы не будем, определим только объекты и функцию перегрузки оператора – ( минус).
class string {
char *text ;
int len ;
public: …
}
void string::operator – ( char ll) // подпрограмма удалений из строки всех вхождений символа ll.
{ int i, j ;
for ( i=0 ; i<len ; i++)
if ( text[i]==ll )
{
for ( j=i+1 ; j<len ; j++ )
text[j-1] = text[j] ;
len -- ;
text[len] = NULL ;
}
}
main()
{ string data(“ любые слова “) ;
data = data – ‘a’ ;
}
Примечание, чтобы такая программа работала нужно обязательно перегрузить еще оператор присваивания для строки.
Неявный указатель *this.
Каждый объект класса имеет свою копию член-данных, например копию объектов А и С.
cmatr A(x, 5, 3) , C(5, 3) ;
А член-функции (методы) существуют только в одном экземпляре.
A.func() ; C.func() ;
Как же функция разбирается с данными какого объекта ей надо работать?
Установка соответствия член-данного и функции осуществляется при помощи неявного указателя this. При вызове функции ей передается неявный аргумент, который обозначает конкретный объект класса.
A.func() ;
Функции func() передается указатель на объект А, this - адрес А . Использовать this явно нет необходимости в большинстве случаев он нужен тогда, когда мы работаем с указателем на объект.
Пример функции возвращающей адрес текущего объекта.
cmatr cmatr:: operator = (cmatr &a)
{ for ( int i=0 ; i<n ; i++)
for ( int j=0 ; j<k ; j++)
this->m[i][j]=a.m[i][j] ;
return (*this) ;
}