Лекции по курсу «Программирование» Лекция 6. Типы данных, определяемые пользователем. Переименование типов, перечислимые типы, структуры, объединения, классы. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Типы данных, определяемые пользователем Наряду со встроенными типами данных, в языке С++ существуют ряд инструментов для создания собственных типов данных. К ним относятся: - оператор переименования типов - перечислимые типы - структуры - объединения - классы © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Переименование типов Ключевое слово typedef Переименование обычных типов: typedef тип новое_имя_типа; Переименование типов-массивов: typedef тип новое_имя_типа [число элементов]; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Переименование типов Ключевое слово typedef (пример) Переименование типа char на byte: typedef char byte; Введение нового типа myarray как массива из 100 элементов типа int: typedef int myarray[100]; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Перечислимые типы Определение перечислимого типа enum имя_типа {список констант}; Пример enum color {red, green, blue}; Представляется значением 0 Представляется значением 1 © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Представляется значением 2 Перечислимые типы Определение перечислимого типа – ещё один пример enum color {white = -1, red, green, blue}; Представляется значением -1 Представляется значением 0 © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Представляется значением 1 Представляется значением 2 Перечислимые типы Пример использования перечислимого типа enum color {white , red, green, blue}; void main( ) {color x; …………… x=red; …………… } © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Структуры Определение структуры struct имя_типа {список элементов}; Пример struct humen { char name[20]; char sirname[20]; int birthyear; }; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Структуры Доступ к элементам структуры операцией «точка» struct humen { char name[20]; char sirname[20]; int birthyear; }; void main( ) {humen x1; x1.birthyear=1991; } © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Структуры Доступ к элементам структуры операцией «стрелка» struct humen { char name[20]; char sirname[20]; int birthyear; }; void main( ) {humen *px1; px1 = new humen; x1->birthyear=1991; } © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Структуры Вывод: запись px1->birthyear эквивалентна записи (*px1).birthyear. Если имеем дело с самой переменнойструктурой, значит для доступа к полям используем операцию «точка», если с указателем на переменнуюструктуру – операцию «стрелка». © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Структуры Расположение полей структуры в памяти Указатель на структуру Поле 1 © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Поле 2 Поле 3 Объединения Определение объединения union имя_типа {список элементов}; Пример union realnumber { float flo; double dbl; long double ldb; }; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Объединения Важно: отличие структуры от объединения состоит в том, что структура может одновременно хранить все свои поля, а объединение – только одно из полей. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Объединения Расположение полей объединения в памяти Поле 2 Указатель на объединение Поле 1 © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Поле 3 !! То есть занимаемые полями области памяти перекрываются Классы и объекты Определение понятия «класс» и «объект» Классом называется специальный создаваемый пользователем тип данных, содержащий в себе элементы-данные (поля) и элементы-функции (методы). Объектом называется переменная – представитель класса, то есть имеющая тип, описанный каким-либо классом. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Классы и объекты Пример объявления класса point class point { public int x; int y; void show(int color); private int color; }; Спецификаторы доступа © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Элементы-данные Элемент-функция Классы и объекты Спецификаторы доступа public – спецификатор доступа, означающий, что перечисленные за ним переменные доступны как функциям данного класса, так и любым другим функциям (открытый доступ); private – спецификатор доступа, означающий, что перечисленные за ним переменные доступны только функциям данного класса (закрытый доступ); protected – спецификатор доступа, означающий, что перечисленные за ним переменные доступны как функциям данного класса, так и функциям классов, производных от него. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Классы и объекты Доступ к элементам класса (пример) point p1, p2; p1.x=20; p1.y=30; p1.show(5); Для доступа к элементам класса может также применятся операция «стрелка» (если имеем дело не самой переменной, а с указателем на неё – аналогично структурам). © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Классы и объекты Объявление функций-элементов класса внутри класса (пример) class point { public int x; int y; void show(int color) { Реализация функции show }; private int color; }; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Классы и объекты Объявление функций-элементов класса вне класса (пример) class point { public int x; int y; void show(int color); private int color; }; void point::show(int color) { Реализация функции show }; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Классы и объекты Указатель this Ключевое слово this является синонимом указателя на текущую переменную – представитель класса. Оно используется для получения функциями класса доступа к той переменной – представителю класса, для которой они вызваны. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Классы и объекты Указатель this – пример использования class complex { public double re; double im; double modul( ); }; double complex::modul() {double r; r = sqrt((this->re)*(this->re)+(this->im)*(this->im)); return r; } © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Наследование Понятия «родитель» и «потомок» Класс в С++ может наследовать данные и функции от одного или нескольких базовых классов. Сам класс в этом случае называется классом-потомком по отношению к базовым классам. Базовые классы называются родительскими классами. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Наследование Синтаксис объявления производного класса class имя_класса ключ_доступа имя_базового_класса { Тело объявления класса; }; Ключ_доступа здесь – одно из слов private, public или protected. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Наследование Правило доступа к элементам базового класса через производный Права доступа, определяемые базовым классом (родительским), остаются неизменными, если они такие же или строже, чем у производного класса (классапотомка). © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Наследование Пример описания базового класса и класса-потомка class point { public int x; int y; void show(int color); private int color; }; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Родительский класс Наследование Пример описания базового класса и класса-потомка (продолжение) class circle:public point { public int r; void show(int color); Класс-потомок }; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Наследование Пример описания базового класса и класса-потомка (продолжение) Теперь можно объявить переменную типа circle и использовать как её собственные элементы, так и унаследованные ею от типа point circle c1; c1.x = 10; c1.y = 20; c1.r = 100; c1.show(2); © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Специальные функции – элементы класса Перечень специальных функций – элементов класса Специальными функциями – элементами класса называют функции, которые компилятор может вызывать неявно. К ним относятся: - Конструктор - Деструктор - Конструктор копии - Операция присваивания - Операция new - Операция delete - Функции преобразования типов © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Специальные функции – элементы класса Конструктор Функция конструктор служит для создания объекта, и вызывается всегда при создании переменной. Если она не описана, то вызывается конструктор по умолчанию, выделяющий память под размещение переменной. Имя конструктора совпадает с именем класса. Конструктор не может возвращать значений и не наследуется. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Специальные функции – элементы класса Деструктор Деструктор вызывается при уничтожении объектов. Именем деструктора является имя класса, перед которым стоит знак ~ . Деструктор не имеет параметров, не может возвращать значений и не наследуется. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Специальные функции – элементы класса Конструктор и деструктор - пример class string{ public string ( ); ~string ( ); }; string::string ( ) {Тело конструктора} string::~string ( ) {Тело деструктора} © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Перегрузка операций Сущность задачи перегрузки операций Язык С++ позволяет переопределять (перегружать) для классов существующие обозначения операций. Благодаря перегрузке класс можно «заставить» вести себя подобно встроенному типу. Функции-операции, реализующие перегрузку, имеют вид: operator операция(операнды); © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Перегрузка операций Список операндов operator операция(операнды); Если функция-операция является элементом класса, то первый операнд соответствующей операции будет самим объектом, для которого вызвана операция. В случае одноместной операции список операндов будет пуст. Для двухместных операций функция будет иметь один параметр, соответствующий второму операнду © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Перегрузка операций Правила перегрузки операций - приоритет для перегруженных операций остаётся неизменным; - нельзя изменить поведение операции по отношению к встроенному типу; - функция-операция не может иметь аргументов по умолчанию; - Функции-операции, кроме присваивания, наследуются. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Перегрузка операций Примеры операций, которые можно перегрузить = *, /, +, -, % [] new, delete присваивание арифметические операции индексирование операторы динамического размещения переменных & взятие адреса * разыменование и некоторые другие ….. © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Перегрузка операций Пример, иллюстрирующий перегрузку операции + class complex { public double re; double im; complex complex::operator+(complex v2); }; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Перегрузка операций Пример, иллюстрирующий перегрузку операции + (продолжение) complex complex::operator+(complex v2) {complex help; help.re=this->re+v2.re; help.im=this->im+v2.im; return help; }; © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС Перегрузка операций Пример, иллюстрирующий перегрузку операции + (продолжение) После объявления класса и переопределения для него операции сложения, можно написать: complex x1, x2, x3; x1.re=1; x1.im=2; x2.re=5; x2.im=4; x3=x1+x2; То есть по отношению к операции + созданный нами класс complex начал вести себя подобно встроенному типу © В.М. Гриняк, доц. каф. ИСКТ ВГУЭС