- •Операторы динамического распределения памяти
- •Перегрузка функций и операций
- •Объекты и классы Класс как обобщение структуры
- •Определение первичного класса
- •Перегрузка операций
- •Конструкторы
- •Список инициализации
- •Деструктор
- •Дружественные классы
- •Статические элементы класса
- •Шаблоны функций
- •Контейнерные классы Шаблоны классов
- •Параметризованные очереди и стеки
- •Бинарные деревья
- •Определение класса множества
- •Производные классы Доступ к полям и функциям базового класса
- •Класс дерева поиска
- •Параметризованный связный список
- •Множественное наследование
- •Виртуальные классы
- •Виртуальные функции Переопределение составной функции
- •Организация списка объектов различного типа
- •Виртуальные деструкторы
- •Абстрактные классы
Дружественные классы
Например, если мы хотим перегрузить операцию вывода на экран элементов двумерного массива, определенного выше классом twomas, то нам будет нужен доступ к закрытым членам класса. Для обеспечения этого доступа в теле класса следует объявить прототип функции
friend ostream& operator << (ostream& o, twomas& d);
и определить операцию вывода с помощью внешней подпрограммы (функции):
ostream& operator << (ostream& o, twomas& d)
{
int i, j;
for(i = 1; i <= d.n; i++)
{
for(j = 1; j <= d.n; j++)
o << d(i, j) << ‘ ‘;
o << “\n”;
}
return o;
}
Пример. Определим класс графического окна, в которое будет выводиться график линейной функции. Линейная функция определяется как класс.
#include <graphics.h>
#include <conio.h>
class Wnd; // Прототип класса Wnd
// Класс - функция
class Func
{
// Закрытые элементы
double k, b; // y = kx + b
friend class Wnd; // Объявление дружественного класса
public: // Общедоступные элементы
Func(double k1, double b1=0): k(k1), b(b1) {} // Конструктор
};
// Класс окна
class Wnd
{
// Закрытые элементы
int xleft, xright, ytop, ybot; // Реальные координаты окна
double xmin, ymin, xmax, ymax; // Относительные координаты окна
public: // Общедоступные элементы
// Конструктор
Wnd(double x0, double y0, double x1, double y1,
int xl=0, int yt=0, int xr=639, int yb=479):
xmin(x0), ymin(y0), xmax(x1), ymax(y1),
xleft(xl), ytop(yt), xright(xr), ybot(yb) {}
Wnd& operator << (Func); // Перегрузка операции <<
};
// Перегрузка операции <<
Wnd& Wnd::operator << (Func f)
{
double xkof, ykof; // Коэффициенты перевода относительных
// координат в реальные
xkof = (xright-xleft)/(xmax-xmin);
ykof = (ybot-ytop)/(ymax-ymin);
rectangle(xleft, ytop, xright, ybot); // Рамка
line(xleft,
ytop+(ymax-ymin)*ykof/2,
xright,
ytop+(ymax-ymin)*ykof/2); // Ось х
line(xleft+(xmax-xmin)*xkof/2,
ytop,
xleft+(xmax-xmin)*xkof/2,
ybot); // Ось у
line((xright - xleft)/2 + xmin*xkof,
(ybot - ytop)/2 - (xmin*f.k+f.b)*ykof,
(xright - xleft)/2 + xmax*xkof,
(ybot - ytop)/2 - (xmax*f.k+f.b)*ykof); // Вывод функции
return (*this);
}
void main()
{
int gd=DETECT, gm;
Wnd w(-5, -3, 5, 3); // Определение окна
Func phi(1, 1); // Определение функции
initgraph(&gd, &gm, ""); // Инициализация графики
w<<phi; // Вывод функции phi в окно w
getch(); // Ожидание нажатия клавиши
closegraph(); // Закрытие графики
}
Результаты работы программы
Статические элементы класса
Пример. Определим класс строки, содержащий подпрограмму, возвращающую количество объектов этого класса, находящихся в области видимости. Определим статическую переменную many целого типа. Конструктор объекта будет увеличивать эту переменную на 1, а деструктор – уменьшать на 1. Распределение области памяти, занимаемой объектами класса, приведено на рис. 2.1.
Int many |
- поле, содержащееся в каждом объекте |
|||
Объект char *s int length |
Объект char *s int length |
|
Объект char *s int length |
- поля объектов, содержащие указатели на строки и длины строк |
Рис. 2.1. Распределение области памяти
Приведём текст программы:
#include <iostream.h>
#include <conio.h>
#include <string.h>
class Vstring
{
// Закрытые элементы
static int many; // Количество объектов Vstring
char *s; // Строка
int length; // Длина строки
public: // Общедоступные элементы
Vstring(char *text) // Конструктор
{
length = strlen(text); // Вычисление длины
s = new char[length+1]; // Выделение памяти
strcpy(s, text); // Копирование строки
many++; // Увеличение числа объектов
}
~Vstring() // Деструктор
{
delete s; // Освобождение памяти
many--; // Уменьшение числа объектов
}
static int Number() { return many; } // Статическая функция
// Общая функция
void get()
{
cout << s << '\n';
}
};
int Vstring::many = 0; // Установка начального числа объектов
void main()
{
clrscr(); // Очистка экрана
cout << "Количество объектов Vstring: " << Vstring::Number() << '\n';
Vstring u("12345");
cout << "Количество объектов Vstring: " << Vstring::Number() << '\n';
Vstring v("12345");
cout << "Количество объектов Vstring: " << Vstring::Number() << '\n';
cout << "Значение объекта v: ";
v.get();
cout << '\n';
for(int i = 0; i < 3; i++)
{
cout<<"Количество объектов Vstring: "<<Vstring::Number()<<'\n';
Vstring v("12345");
cout<<"Количество объектов Vstring: "<<Vstring::Number()<<'\n';
getch();
}
}
Результаты работы программы
Количество объектов Vstring: 0
Количество объектов Vstring: 1
Количество объектов Vstring: 2
Значение объекта v: 12345
Количество объектов Vstring: 2
Количество объектов Vstring: 3
Количество объектов Vstring: 2
Количество объектов Vstring: 3
Количество объектов Vstring: 2
Количество объектов Vstring: 3