
- •1 Парадигми та мови програмування
- •1.1 Процедурне програмування
- •1.2 Об'єктне (модульне) програмування
- •1.3 Об'єктно-орієнтовне програмування
- •2 Програмне середовище
- •3 Базові поняття програмування
- •4 Процедурно-орієнтоване програмування
- •4.1 Функції
- •4.2 Вбудовані (inline) функції
- •4.3 Передача параметрів
- •4.4 Обчислення значення функцій
- •4.4. Обчислення значення функції — вихід із функції; особливості повернення та використання іменованого значення, іменованої константи
- •4.5 Рекурсія
- •4.6 Довизначення (overloading) функцій
- •4.6. Довизначення (overloading) функцій
- •4.7 Узагальнені функції (function template)
- •4.8 Непряме використання функцій: указники на функції, їх тип, ініціалізація і присвоєння
- •4.9 Видимість
- •4.10 Тривалість життя об’єктів
- •5 Об'єктне програмування
- •5.1 Класи і об'єкти, члени класів
- •5.2 Інтерфейс класу, реалізація класу; визначення і оголошення класу
- •5.3 Створення і ініціалізація об'єктів, довизначення конструкторів, замовчуваний конструктор, копіювання, поверхневе і глибоке копіювання, ініціалізація і присвоєння, копіювальний конструктор
- •5.4 Cтатичні члени класів і статичні класні функції
- •5.5 Константні об'єкти, константні функції, змінювані члени константних об'єктів (mutable)
- •5.6 Поточний об'єкт this, указники на члени класу і класні функції, порівняння з указниками на (позакласні) функції, указники на статичні члени класу
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.8 Клас string: конструктори і присвоєння рядків, операції, відкладене копіювання
- •5.9 Параметризовані класи (class template): визначення шаблону, конкретизація
- •6 Об'єктно-орієнтовне програмування
- •6.1 Ієрархія об’єктів і ієрархія класів
- •6.2 Відкрите, закрите і захищене успадкування, успадкування типу і успадкування реалізації; абстрактні класи
- •6.3 Створення похідних об'єктів
- •6.4 Статичне і динамічне зв’язування
- •6.5 Успадкування із спільного базового класу. Кратне (multiple) успадкування. Віртуальне успадкування, порядок виклику конструкторів
- •7 Екзаменаційні завдання
- •7 Екзаменаційні завдання
Конспект лекцій по С++
ЗМІСТ
стор.
1 Парадигми та мови програмування 3
1.1 Процедурне програмування 4
1.2 Об'єктне (модульне) програмування 5
1.3 Об'єктно-орієнтовне програмування 6
2 Програмне середовище 7
3 Базові поняття програмування 10
4 Процедурно-орієнтоване програмування 18
4.1 Функції 18
4.2 Вбудовані (inline) функції 19
Вбудовані (inline) функції, порівняння з макровизначеннями, закриті функції 19
4.3 Передача параметрів 21
4.3. Передача параметрів значенням, особливості передачі параметрів у випадку указників, псевдонімів, псевдонімів сталих, псевдонімів указників, масивів, псевдонімів масивів; замовчувані значення параметрів; перетворення типів при передачі параметрів 21
4.4 Обчислення значення функцій 27
4.4. Обчислення значення функції — вихід із функції; особливості повернення та використання іменованого значення, іменованої константи 27
4.5 Рекурсія 29
4.6 Довизначення (overloading) функцій 30
4.6. Довизначення (overloading) функцій 30
4.7 Узагальнені функції (function template) 31
Узагальнені функції (function template) 31
4.8 Непряме використання функцій: указники на функції, їх тип, ініціалізація і присвоєння 33
Непряме використання функцій 33
4.9 Видимість 35
4.10 Тривалість життя об’єктів 37
5 Об'єктне програмування 40
Принцип інкапсуляції даних і дій 40
5.1 Класи і об'єкти, члени класів 44
5.2 Інтерфейс класу, реалізація класу; визначення і оголошення класу 50
5.3 Створення і ініціалізація об'єктів, довизначення конструкторів, замовчуваний конструктор, копіювання, поверхневе і глибоке копіювання, ініціалізація і присвоєння, копіювальний конструктор 52
5.4 Cтатичні члени класів і статичні класні функції 58
5.5 Константні об'єкти, константні функції, змінювані члени константних об'єктів (mutable) 62
5.6 Поточний об'єкт this, указники на члени класу і класні функції, порівняння з указниками на (позакласні) функції, указники на статичні члени класу 68
5.7 5.8. Довизначення (overloading) операцій 77
5.7 5.8. Довизначення (overloading) операцій 84
5.7 5.8. Довизначення (overloading) операцій 90
5.7 5.8. Довизначення (overloading) операцій 94
5.7 5.8. Довизначення (overloading) операцій 98
5.7 5.8. Довизначення (overloading) операцій 102
5.8 Клас string: конструктори і присвоєння рядків, операції, відкладене копіювання 106
5.9 Параметризовані класи (class template): визначення шаблону, конкретизація 114
6 Об'єктно-орієнтовне програмування 117
6.1 Ієрархія об’єктів і ієрархія класів 117
6.2 Відкрите, закрите і захищене успадкування, успадкування типу і успадкування реалізації; абстрактні класи 122
6.3 Створення похідних об'єктів 127
6.4 Статичне і динамічне зв’язування 128
6.5 Успадкування із спільного базового класу. Кратне (multiple) успадкування. Віртуальне успадкування, порядок виклику конструкторів 134
7 Екзаменаційні завдання 137
7 Екзаменаційні завдання 137
8 Перевірте свої знання по С++ 137
Вступ
Цей конспект виник в результаті викладання автором продовження курсу програмування студентам, що вже не були початківцями, а мали досвід програмування принаймні в Паскалі. Це дозволило не зупинятися на традиційних проблемах початкового курсу програмування. Будемо виходити з того, що традиційні структури керування і структури даних добре відомі, так само як техніка програмування рекурентних співвідношень, індуктивних функцій, дослідження інваріантів. Повинні бути відомі також засоби алгоритмічної декомпозиції, наприклад, на рівні розробки алгоритмів сортування і пошуку, обробки дерев, списків, інших структур даних. Для розуміння курсу цілком достатньо підготовки в обсязі двох відомих книг Н.Вірта[1,2 ].
Головна мета курсу — оволодіння технікою об'єктно-орієнтованого програмування на прикладі найбільш поширеної мови програмування С++. Мова С++ багатопарадигменна, а тому її вивчення служить доброю базою для порівняльного аналізу парадигм імперативного програмування. Практика спілкування з студентами дозволила виділити найважчі для розуміння конструкції, підібрати прозоріші приклади.
Конспект лекцій з об'єктно-орієнтованого програмування не замінить посібників з мови програмування С++. Він покликаний допомогти у встановленні послідовності вивчення матеріалу, виділити найважливіші з точки зору розробки програмного забезпечення моменти, дати змістовні приклади. Передбачається, що деталі синтаксису і семантики мовних конструкцій вивчатимуться самостійно за наведеною літературою.
Серйозною виявилася проблема української термінології. В програмуванні вона, на жаль, ще не склалася. Доступні книги російськомовні, термінологія російською мовою в основному склалася, хоча теж не завжди встигає за розвитком галузі. Деякі терміни, як наприклад, frame work , tool kit , design pattern ще чекають на влучні переклади, інші перекладаються дослівно навіть в тих випадках, коли можна вживати більш звичні терміни, наприклад, довизначення або розширення замість “ перегрузки функций ”. Значну допомогу в перекладі термінології надають англо-українські та російсько-українські словники з інформатики та обчислювальної техніки, зокрема підготовлені в Національному університеті ім. Тараса Шевченка. Але самі слоники ще не норма, а швидше експеримент, а тому проблему термінології вони повністю не розв'язують. Підбираючи власний варіант перекладу терміну, я керувався здоровим глуздом та академічним виданням словника української мови.
При роботі над рукописом були використані книги розробників С++ [3,4] , які я рекомендую студентам для поглибленого вивчення, а також як довідковий матеріал. Значний вплив на зміст і будову конспекту справила на жаль мало відома у нас книга Д.Марка [5] , визначивши загальний стиль пояснення проблем на прикладах.
Автор буде глибоко вдячний кожному, хто висловить свої зауваження до конспекту, які можна надіслати автору на адресу vlad@unicyb.kiev.ua
1 Парадигми та мови програмування
Парадигми та мови програмування
Всередині кожної з двох основних парадигм виділяють парадигми менші. В цьому курсі ми займатимемося наказовими парадигмами, але не забуватимемо про існування інших. Декларативні парадигми дозволяють нам точніше висловлюватися про наказові програми. Зауважимо, що сам професор Дж.Бекус — винахідник першої мови наказового програмування Фортран — успішно працював над пошуком нових парадигм, зокрема декларативної парадигми функціонального програмування. Одночасне застосування кількох парадигм, або мультипарадигменність дозволяє нам глянути на задачу під різними кутами зору, завдяки чому збільшуються шанси пошуку кращого рішення.
Підкреслимо, що парадигма програмування — це спосіб мислення розробника програми. Мова програмування може підтримувати або не підтримувати ту чи іншу парадигму. В першому випадку застосування парадигми стає зручним, тобто простим, безпечним і ефективним. Ми розглянемо три основних наказових парадигми — процедурне, об’єктне (модульне) і об’єктно-орієнтоване (ієрархічне) програмування і одну допоміжну — узагальнене програмування. Всі вони підтримуються мовою програмування С++, яка розвинулася з мови процедурного програмування С. Огляд поширених мов програмування і відповідних парадигм подано на малюнку.
1.1 Процедурне програмування
Процедурне програмування
Процедурне програмування подає програму у вигляді набору алгоритмів, для оформлення яких можуть застосовуватися іменовані програмні блоки — процедури і функції. В останньому випадку передбачається наявність механізмів передачі параметрів і поверненні результату.
Спочатку процедурне програмування користувалося довільними засобами керування, в тому числі, переходом за міткою — одним з найбільш вживаних операторів керування в Фортрані. Ось приклад програмного тексту з Фортрану
C КВАДРАТНИЙ КОРІНЬ З ДІЙСНОГО ЧИСЛА
REAL FUCTION ROOT (A)
S=A
IF (A.EQ.0) GO TO 20
10 T=(S+A/S)*.5
IF (ABS((T-S)/T).LE.1.T-6) GO TO 20
S=T
GO TO 10
20 ROOT=S
END
В 1968 році голландський вчений Е.Дейкстра вперше звернув увагу на проблеми, що виникають у програмах з неконтрольованими переходами, в 1970 році проголосив новий напрямок, який він назвав структур(ова)ним програмуванням. Структурне програмування — це варіант процедурного, що вживає три типи структур керування: послідовне виконання дій, розгалуження і цикл. Не дивно, що Фортран не підтримував цю парадигму — в наборі його засобів не було циклів за умовами. Починаючи з Алголу, а особливо в Паскалі, цикли стають основним засобом організації обчислень в програмі:
function root(a: real,eps:real): real;
var s, t: real;
begin
s:=a*0.5;
repeat
t:=s;
s:=(s+a/s)*O.5;
until abs(s-t)/s< end root:="s;" do>
Автор Паскалю, професор Н.Вірт, відібрав до створюваної ним мови програмування лише прості в поясненні і легкі в реалізації конструкції. Завдяки сильній типізації програми в Паскалі відзначаються високою надійністю, вони мобільні завдяки закладеній в них концепції Паскаль-машини, їх легко читати і розуміти завдяки дисципліні програмування, продиктованої вжитою парадигмою.
Але разом з цим застосування Паскалю гальмувалося саме складністю виходу за межі віртуальної машини, потребою ефективного використання наявної апаратури. Головним критерієм, вжитим Б.Керніганом і Д.Річі до створеної ними мови С, стала саме гнучкість використання особливостей конкретної апаратури і ефективність виконання програм.