|
![]() Пошук
Пошук по блогу. Мінімум 4 символи Профіль
Сторінки блогу
Категорії
Скачати
Відео
Музика
Останні статті
ТОП 10
Останні файли
Останні пісні
ТОП 10 файлів
ТОП 10 пісень
Архів
Галерея
Наші друзі
Банери:
Статистика
![]() На нашому блозі Коментарів: 93 Коментарі до файлів: 23 Зображень: 680 Відео: 68 Пісень: 7 Файлів: 60 Користувачів: 11 Адміністраторів: 1 Реклама
|
Все про C++ для початківців і не тільки Частина 2 Автор: admin Дата публікації: 21 червня Частина 1 можете прочитати тут Об'єктно-орієнтовані особливості мови Сі++ додає до Сі об'єктно-орієнтовані можливості. Він вводить класи, які забезпечують три найважливіші властивості ООП: інкапсуляцію, успадкування і поліморфізм. Проблеми старого підходу В мові C основним способом організації даних були структури. Структура складається з набору полів, які ніяк не захищені. Якщо елементи структури мають змінну довжину, їх представляють у вигляді вказівників. Виділення і звільнення пам'яті під ці вказівники робляться вручну. Так, наприклад, одновимірний масив змінної довжини в мові C з перевіркою меж може представлятися таким чином:
struct Array {
void FreeArray (const struct Array*); Така реалізація небезпечна і неефективна з багатьох причин:
Мова Сі++, використовуючи ООП, усуває всі ці проблеми. Інкапсуляція Основним способом організації інформації в Сі++ є класи. На відміну від типу структура (struct) мови Сі, що складається тільки з полів, клас (class) Сі++ складається з полів і функцій-членів або методів (англ. member functions). Поля бувають публічними (public), захищеними (protected) і приватними (private). У Сі++ тип структура аналогічний типу клас, відмінність в тому, що за умовчанням поля і функції-члени у структури публічні, а у класу — приватні. З публічними полями можна робити зовні класу все, що завгодно. До захищених і приватних полів не можна звертатися ззовні класу, щоб не порушити цілісність даних класу. Спроба такого звернення викличе помилку компіляції. До таких полів можуть звертатися тільки функції-члени класу (а також так звані функції-друзі і функції-члени класів-друзів; про поняття друзів в C++ дивись нижче.) Поза тілом функцій-членів (а також друзів) захищені і власні поля недоступні навіть для читання. Такий захист полів називається інкапсуляциєю. Використовуючи інкапсуляцію, автор класу може захистити свої дані від некоректного використання. Крім того, вона замислювалася для полегшення сумісної розробки класів. Малося на увазі, що зміна способу зберігання даних, якщо вони оголошені як захищені або приватні не вимагає відповідних змін в класах, які використовують змінений клас. Наприклад, якщо в старій версії класу дані зберігалися у вигляді лінійного списку, а в новій версії — у вигляді дерева, ті класи, які були написані до зміни формату зберігання даних, переписувати не буде потрібно, якщо дані були приватними або захищеними (у останньому випадку — якщо використовуючі класи не були класами-нащадками), оскільки жоден з них цих класів не міг би безпосередньо звертатися до даних, а тільки через стандартні функції, які в новій версії мають вже коректно працювати з новим форматом даних. Навіть оператор доступу operator [] може бути визначений як така стандартна функція. Функції-члени, як і поля, можуть бути публічними, захищеними і приватними. Публічні функції може викликати будь-хто, а захищені і власні — тільки функції-члени і друзі. Використовуючи інкапсуляцію, структуру Array з попереднього розділу можна переписати таким чином:
class Array { Тут масив а має 4 публічних функції-члена і 2 захищених поля. Описувач inline означає, що замість виклику функції її код підставляється в точку виклику, що вирішує проблему неефективності. Опис функцій в тілі класу В тілі класу можна вказати тільки заголовок функції, а можна описати всю функцію. У другому випадку вона вважається вбудованою (inline), наприклад:
class Array { і так далі. Конструктори і деструктори Проте в приведеному прикладі не вирішена важлива проблема: функції Alloc і Free як і раніше треба викликати вручну. Інша проблема даного прикладу — небезпека оператора присвоєння. Для вирішення цих проблем в мову були введені конструктори і деструктори. Конструктор викликається кожного разу, коли створюється об'єкт даного типу; деструктор — при знищенні. При перетвореннях типів, присвоєнні, передачі параметра теж викликаються конструктори і при необхідності деструктори. З конструкторами і деструкторами клас виглядає так:
class Array { Тут Array::Array — конструктор, а Array::~Array — деструктор. Конструктор копіювання (англ. copy constructor) Array::Array(const Array&) викликається при присвоєнні. Тепер об'єкт класу Array не можна зіпсувати: як би ми його не створювали, що б ми не робили, його значення буде коректним, тому що конструктор викликається автоматично. Всі небезпечні операції з вказівниками заховані в захищені функції.
Array a(5); // викликається Array::Array(int) Оператор new теж викликає конструктори, а delete — деструктори. За умовчанням, кожен клас має конструктор без параметрів і деструктор. Конструктор без параметрів за умовчанням викликає конструктори всіх елементів, а деструктор — їх деструктори. Інші конструктори за умовчанням не визначені. Клас може мати скільки завгодно конструкторів (з різними наборами параметрів), але тільки один деструктор (без параметрів). Інші можливості функцій-членів Функції-члени можуть бути і операціями:
class Array { Такі функції не мають права змінювати поля класу (окрім полів, визначених як mutable). Якщо вони намагаються це зробити, компілятор повинен видати повідомлення про помилку. Успадкування Для створення класів з доданою функціональністю вводять успадкування. Клас-нащадок має поля і функції-члени базового класу, але не має права звертатися до приватних (private) полів і функцій базового класу. У цьому і полягає різниця між приватними і захищеними членами. Клас-нащадок може додавати свої поля і функції або перевизначати функції базового класу. За умовчанням, конструктор нащадка без параметрів викликає конструктор базового класу, а потім конструктори доданих елементів. Деструктор працює в зворотному порядку. Інші конструктори доводиться визначати кожного разу наново. На щастя, це можна зробити викликом конструктора базового класу.
class ArrayWithAdd : public Array { Нащадок — це більш ніж базовий клас, тому він може використовуватися скрізь, де використовується базовий клас, але не навпаки. Успадкування буває публічним, захищеним і власним. При публічному спадкуванні, публічні і захищені члени базового класу зберігають свій статус, а до приватних не можуть звертатися навіть функції-члени нащадка. Захищене спадкування відрізняється тим, що при нім публічні члени базового класу є захищеними членами нащадка. При приватному успадкуванні, до жодного члена базового класу навіть функції-члени нащадка права звертатися не мають. Як правило, публічне спадкування зустрічається значно частіше за інші. Клас може бути нащадком декількох класів. Це називається множинним спадкуванням. Такий клас володіє полями і функціями-членами всіх його предків. Наприклад, клас FlyingCat може бути нащадком класів Cat і FlyingAnimal.
class Cat { Поліморфізм Поліморфізмом в програмуванні називається перевизначення нащадком функцій-членів базового класу, наприклад
class Figure { В даному прикладі, яка з функцій буде викликана — Circle::Draw(), Square::Draw() або Figure::Draw(), визначається під час компіляції. Наприклад, якщо написати
Figure* x = new Circle(0,0,5); Але в C++ є і динамічний поліморфізм, коли функція, що викликається, визначається під час виконання. Для цього функції-члени повинні бути віртуальними.
class Figure { В цьому випадку для кожного елементу буде викликана Square::Draw() або Circle::Draw() залежно від виду фігури. Чисто віртуальною функцією називається функція-член, яка не визначена в базовому класі, а тільки в нащадках:
class Figure { Ось це = 0 і означає, що функція чисто віртуальна. Абстрактним класом називається такий, у якого є хоч би одна чисто віртуальна функція-член. Об'єкти таких класів створювати заборонено. Абстрактні класи використовуються як інтерфейси. Друзі Функції-друзі — це функції, що не є функціями-членами, проте мають доступ до захищених і власних полів і функцій-членів класу. Вони повинні бути описані в тілі класу як friend. Наприклад:
class Matrix { Тут функція Multiply може звертатися до будь-яких полів і функцій-членів класу Matrix. Існують також класи-друзі. Якщо клас A — друг класу B, то всі його функції-члени можуть звертатися до будь-яких полів і функцій членів класу B. Наприклад:
class Matrix { Проте в С++ не діє правило «друг мого друга — мій друг». За стандартом C++03 вкладений клас не має прав доступу до закритих членів охоплюючого класу і не може бути оголошений його другом (це виходить з визначення терміну друг як нечлена класу). Проте, багато розповсюджених компіляторів порушують обидва ці правила (може, зважаючи на сукупну дивність цих правил). Переглядів: 123
Коментарі Коментар добавив-(ла): Pidut Ти придурок. Дуже "цікаво"))) Писати навчися спочатку!!! "друг як нечлена класу" Добавити коментар |
|
Copyright © 2009 Kemping.te.UA Design by |