
- •220300 - Системы автоматизированного проектирования
- •Тема 2. Технологии программирования
- •Тема 2. Технология разработки крупных приложений
- •Структуры
- •Структуры и функции
- •Массивы структур
- •Поиск в массиве структур
- •Вложенность структур
- •Рекурсия
- •Алгоритм быстрой сортировки
- •Массивы структур и бинарные файлы
- •Динамические структуры данных
- •Линейные списки
- •Очереди
- •Контрольная работа
- •Объектно-ориентированное программирование. Классы
- •Конструкторы
- •Перегруженные конструкторы
- •Определение методов класса вне класса
- •Объекты, возвращаемые функцией (методом)
- •Структуры и классы
- •Классы и память
- •Статические данные класса
- •Константные методы
- •Деструкторы
- •Массивы и классы
- •Массивы объектов
- •Строки Строковый тип или стандартный класс string
- •Тип строк AnsiString
- •Перегрузка операций
- •Перегрузка арифметических операций
- •Перегрузка операций сравнения
- •Перегрузка операции приведения типа
- •Преобразования объектов в основные типы и наоборот
- •Преобразование объектов классов в объекты других классов
- •Наследование
- •Конструкторы производного класса
- •Перегрузка функций
- •Иерархия классов
- •Общее и частное наследование. Комбинации доступа
- •Множественное наследование
- •Включение. Классы в классах
- •Виртуальные и дружественные функции
- •Абстрактные классы и чистые виртуальные функции
- •Виртуальные деструкторы
- •Виртуальные базовые классы или устранение неоднозначности при множественном наследовании
- •Дружественные функции
- •Дружественные классы
- •Указатель this
- •Многофайловые программы
- •Распознавание нажатых клавиш
Объектно-ориентированное программирование. Классы
Основными свойствами ООП являются инкапсуляция, наследование и полиморфизм. Инкапсуляцией называется объединение данных с функциями их обработки в сочетании со скрытием не нужной для использования этих данных информации. Инкапсуляция позволяет использовать класс в другом окружении и создавать библиотеки классов для применения во многих программах. Наследование – это возможность создания иерархии классов, когда потомки (производные классы) наследуют все свойства своих предков (базовых классов), могут их изменять и добавлять новые. Свойства при наследовании повторно не описываются, что сокращает объём программы. Третьим китом, на котором стоит ООП, является полиморфизм – возможность использовать в различных классах иерархии одно имя для обозначения сходных по смыслу действий и гибко выбирать требуемое действие во время выполнения программы.
Для работы с собственными типами данных требуются специальные функции. Естественно сгруппировать их с описанием этих типов данных в одном месте, а также отделить от её остальных частей.
Класс является абстрактным типом данных, определяемым пользователем, и представляет собой модель реального объекта в виде данных и функций для работы с ними. Данные класса называются полями (по аналогии с полями структуры), а функции класса – методами. Поля и методы называются элементами класса. Описание класса выглядит так:
class Имя {
private:
описание скрытых элементов
public:
описание доступных элементов
};
Спецификаторы доступа private и public управляют видимостью элементов класса. Элементы, описанные после служебного слова private, видимы только внутри класса. Интерфейс класса (методы) описывается после спецификатора public и доступен за пределами класса. Действие любого спецификатора распространяется до следующего спецификатора или до конца класса. Здесь раскрывается ключевая особенность ООП – возможность сокрытия данных, т.е. данные могут быть заключены внутри класса и защищены от несанкционированного доступа функций, расположенных вне класса.
Поля класса:
могут иметь любой тип, кроме типа этого же класса (но могут быть указателями или ссылками на этот класс);
могут быть описаны с модификатором const, при этом они инициализируются только один раз (с помощью конструктора) и не могут изменяться.
Инициализация полей при описании не допускается! Классы могут быть глобальными (объявленными вне любого блока) и локальными (объявленными внутри блока, например, функции или другого класса).
Приведём простой пример, содержащий класс и два объекта этого класса:
class SmallObj { // определение класса
private:
int data; // поле класса
public:
void setdata(int d) { // метод класса, изменяющий значение поля
data = d;
}
void showdata() { // метод класса, отображающий на экран значение поля
cout << " Znachenie polya ravno " << data << endl;
}
};
//---------------------------------------------------------------------------
int main() {
SmallObj s1, s2; // определение двух объектов класса SmallObj
s1.setdata(2001); // вызов метода setdata (инициализация)
s2.setdata(2002);
s1.showdata(); s2.showdata(); // вызов метода showdata (вывод на экран)
getch(); return 0;
}
Класс SmallObj, определённый в этой программе, содержит одно поле данных и два метода. Методы обеспечивают доступ к полю данных класса. Нельзя обратиться к полю класса из главной функции, поскольку доступ к полям возможен только из методов класса. Объединение данных и функций является стержневой идеей ООП (см. рис.).
|
Вы можете столкнуться с ситуациями, когда будет необходимо скрывать функции и обеспечивать свободный доступ к данным класса. Например, если поле класса сделать открытым public: int data; , то в главной функции можно получать доступ к этому полю по аналогии со структурами s2.data = 25; .
Из приведённого выше примера видно, что для получения доступа к методу класса необходимо использовать операцию точки (.), связывающую метод с именем объекта. Синтаксически это напоминает доступ к полям структуры, но в данном случае мы совершаем вызов функции, а не используем значение переменной. Оператор s1.setdata(2001); вызывает метод setdata() объекта s1 . Метод присваивает полю somedata объекта s1 значение, равное 2001. Аналогично, два вызова функции showdata() отобразят на экране значения полей соответствующих объектов.
Рассмотрим пример создания класса, основой для которого послужит структура Tovar, рассматривавшаяся нами ранее и содержащая информацию о товарах на складе.
…
const int N=30;
class Tovar {
private:
char name[N];
int number;
float cena;
public:
void setdata(char* tname, int tnum, float tcen) {
strcpy(name, tname);
number = tnum;
cena = tcen;
}
void showdata() {
cout << "\nNaimenovanie tovara: " << name;
cout << "\nNomer tovara: " << number;
cout << "\nStoimost tovara: " << cena;
}
};
int main() {
Tovar t1, t2;
t1.setdata("Sanki der.", 1100, 231.45); //инициализация значений
t1.showdata();
t2.setdata("Konki beg.", 2211, 134.90);
t2.showdata();
getch(); return 0;
}
В данном примере имеется возможность инициализировать поля класса только в программе. Для получения возможности вводить значения полей класса пользователем необходимо создать в классе соответствующий метод.
class Tovar {
private:
…
public:
void setdata(char* tname, int tnum, float tcen) {
…
}
void getdata() {
cout << "\n Vvedite naimenovanie tovara: "; cin.getline(name, N);
cout << " Vvedite nomer tovara: "; cin >> number;
cout << " Vvedite stoimost tovara: "; cin >> cena;
}
void showdata() {
…
}
};
int main() {
Tovar t1, t2, t3;
…
t3.getdata(); //позволяет вводить данные пользователем
t3.showdata();
getch(); return 0;
}