↓Блог

↓Скачати

↓Відео

↓Інфо


Пошук

Пошук по блогу. Мінімум 4 символи


Профіль

Запамятати мене.


Зареєструватись


Сторінки блогу

Блог

Скачати

Відео

Музика

Фотошоп

Радіо

Інфо

Аналіз сайту

Форум

Категорії

HTML

PHP

CSS

Photoshop

SEO

CMS

Web-дизайн

javascript

Hard Ware

Відео обробка

Вільний блог

Linux

Програмування

Щоденники Дакара

C++

Мій особистий блог

Дизайн

F1

Mobile

Графіка

jQuery

Скачати

Шаблони сайтів

CMS

Для студентів

C++

Стилі для Photoshop

Кисті для фотошопу

Action для Photoshop

LOST

Відео

Відео уроки

Soft для мобільного

Книжки

South Park

OS

Soft

Фільми

Програми для телефонів

Відео

Мої роботи

Кліпи

Авіація

Спорт

Приколи

Трейлери

Джип-спринт

Аеробіка в ТНЕУ 2010

Музика

Rock

Pop

haus

Rap

Останні статті

Conky з темою для Ubuntu і зручною настройкою - красива панель індикаторів

Як ми мішаємо спокою вулиці

Opera Нормальне скачування файлів

Гарячі клавіші Visual Studio 2010

Як роблять зошити

ТОП 10

Урок - Створення відео, за допомогою Windows Movie Maker

Точкові і векторні зображення: порівняльний аналіз

Розбився Ту-154М з президентом Польщі

Ubuntu Server на домашньому комп'ютері. Роздамо інтернет, скачати torrent

Портфоліо у вигляді записного блокнота

Візуалізація даних у вебі: діаграми Ганта

Макет web-сторінки: можливо, все-таки Adobe Illustrator?

Все про C++ для початківців і не тільки

Блок картинок вирівняний по лівій і правій стороні

Зустріч citynet 27.03.2010

Останні файли

онного журналу UserAndLINUX

QuickOffice Premier v6.0.270 для Symbian 9.x S60

Djvu Reader v1.0 alpha для Symbian 9.x S60

PanoMan v3.0.667 для Symbian OS 9.х S60

Theme DIY v1.5 для Symbian OS 9.x S60

Останні пісні

Blue Foundation - Eyes on fire

Blue Foundation - Bonfires

Потап і Настя Каменських - Край мі е рівер

Crezter - I'm a bitch

Robbie Williams - Supreme

ТОП 10 файлів

Стилі для фотошопа - Армія

Кисть для фотошопа - Тропічні метелики

Навчальний курс "Об'єктно-орієнтоване програмування"

Південний Парк (14 сезон: 1 серія) / South Park / 2010 / TVRip

Економічна теорія - світова валютна система

LOST Загублені 6 сезон 13 серія The Last Recruit

Відео уроки по C++

Загублені LOST 6 сезон 4серія

Б. СТРАУСТРАП - ВВЕДЕНИЕ В ЯЗЫК СИ++

EQ BlueTool v.1.1

ТОП 10 пісень

Потап і Настя Каменських - Край мі е рівер

Muse - Supermassive Black Hole

Robbie Williams - Supreme

Crezter - I'm a bitch

Amy MacDonald - This Is The Life

Blue Foundation - Bonfires

Blue Foundation - Eyes on fire

Архів

2010-08

2010-07

2010-06

2010-05

2010-04

2010-03

2010-02

2010-01

2009-12

2009-11

2009-09

Галерея

Днюха Оксани

Квіти

Кемпінг

Кіт

Я

Аватарки

Students life

Портфоліо

Елементи дизайну

Дизайн

ASUS Open 2010

Демотиватори

AFT

СТОК

Miss SIS

Оксанені роботи

Я малий

Дискотека в 8-школі 23.04.10

Арт

Випускний 2010

my HardWare

Friends

Авто

Обробка фотографій

Наші друзі

military

k-design

Блог про блоги

habrahabr

Блог Віктора Бружини

Останє фото

Гербери

Гербери

Банери:
Rambler's Top100


Остаться в живых - LOST. Лучший сайт сериала.
Статистика

Зараз на сайті→4

На нашому блозі

Статей: 131

Коментарів: 93

Коментарі до файлів: 23

Зображень: 680

Відео: 68

Пісень: 7

Файлів: 60

Користувачів: 11

Адміністраторів: 1

Реклама

Все про C++ для початківців і не тільки Частина 2

Автор: admin

Дата публікації: 21 червня

Частина 1 можете прочитати тут


Об'єктно-орієнтовані особливості мови


Сі++ додає до Сі об'єктно-орієнтовані можливості. Він вводить класи, які забезпечують три найважливіші властивості ООП: інкапсуляцію, успадкування і поліморфізм.

Проблеми старого підходу

В мові C основним способом організації даних були структури. Структура складається з набору полів, які ніяк не захищені. Якщо елементи структури мають змінну довжину, їх представляють у вигляді вказівників. Виділення і звільнення пам'яті під ці вказівники робляться вручну. Так, наприклад, одновимірний масив змінної довжини в мові C з перевіркою меж може представлятися таким чином:

struct Array {
double* val;
int len;
};
 

void FreeArray (const struct Array*);
void AllocArray (const struct Array*, int len);
double Elem (const struct Array*, int i);
 void ChangeElem (const struct Array*, int i, double x);

Така реалізація небезпечна і неефективна з багатьох причин:

  • Необхідно викликати FreeArray і AllocArray. Програміст може забути викликати одну з цих функцій, або викликати її дуже рано/запізно, або двічі, або з вказівником на неправильний масив. Все це приводить до помилок, що важко виявити.
  • Функції Elem і ChangeElem повільні.
  • Немає ніякого способу перешкодити програмістам створювати і інші функції для роботи із структурою Array. Ці функції можуть робити з полями len і val будь-що.
  • Немає ніякого способу перешкодити програмістам безпосередньо міняти поля len і val.
  • Присвоєння об'єктів типу struct Array приведе до того, що їх поля val указуватимуть на одну і ту ж область пам'яті. Немає ніякого способу ні заборонити присвоєння, ні змінити таку поведінку.

Мова Сі++, використовуючи ООП, усуває всі ці проблеми.

Інкапсуляція

Основним способом організації інформації в Сі++ є класи. На відміну від типу структура (struct) мови Сі, що складається тільки з полів, клас (class) Сі++ складається з полів і функцій-членів або методів (англ. member functions). Поля бувають публічними (public), захищеними (protected) і приватними (private). У Сі++ тип структура аналогічний типу клас, відмінність в тому, що за умовчанням поля і функції-члени у структури публічні, а у класу — приватні.

З публічними полями можна робити зовні класу все, що завгодно. До захищених і приватних полів не можна звертатися ззовні класу, щоб не порушити цілісність даних класу. Спроба такого звернення викличе помилку компіляції. До таких полів можуть звертатися тільки функції-члени класу (а також так звані функції-друзі і функції-члени класів-друзів; про поняття друзів в C++ дивись нижче.) Поза тілом функцій-членів (а також друзів) захищені і власні поля недоступні навіть для читання. Такий захист полів називається інкапсуляциєю.

Використовуючи інкапсуляцію, автор класу може захистити свої дані від некоректного використання. Крім того, вона замислювалася для полегшення сумісної розробки класів. Малося на увазі, що зміна способу зберігання даних, якщо вони оголошені як захищені або приватні не вимагає відповідних змін в класах, які використовують змінений клас. Наприклад, якщо в старій версії класу дані зберігалися у вигляді лінійного списку, а в новій версії — у вигляді дерева, ті класи, які були написані до зміни формату зберігання даних, переписувати не буде потрібно, якщо дані були приватними або захищеними (у останньому випадку — якщо використовуючі класи не були класами-нащадками), оскільки жоден з них цих класів не міг би безпосередньо звертатися до даних, а тільки через стандартні функції, які в новій версії мають вже коректно працювати з новим форматом даних. Навіть оператор доступу operator [] може бути визначений як така стандартна функція.

Функції-члени, як і поля, можуть бути публічними, захищеними і приватними. Публічні функції може викликати будь-хто, а захищені і власні — тільки функції-члени і друзі.

Використовуючи інкапсуляцію, структуру Array з попереднього розділу можна переписати таким чином:

class Array {
public:
void Alloc(int new_len);
void Free();
inline double Elem(int i);
inline void ChangeElem(int i, double x);
protected:
int len;
double* val;
};

void Array::Alloc(int new_len)
{if (len>0) Free(); len=new_len; val=new double[new_len];}
void Array::Free() {delete [] val; len=0;}
inline double Array::Elem(int i)
{assert(i>=0 && i<len ); return val[i];}
inline void Array::ChangeElem(int i, double x)
{assert(i>=0 && i<len); val[i]=x;}

І далі
Array a;
a.Alloc(10);
a.ChangeElem(3, 2.78);
double b = a.Elem(3);
a.Free();

Тут масив а має 4 публічних функції-члена і 2 захищених поля. Описувач inline означає, що замість виклику функції її код підставляється в точку виклику, що вирішує проблему неефективності.

Опис функцій в тілі класу

В тілі класу можна вказати тільки заголовок функції, а можна описати всю функцію. У другому випадку вона вважається вбудованою (inline), наприклад:

class Array {
public:
void Alloc(int _len)
{if (len==0) Free(); val=new double [len=_len];}

і так далі.

Конструктори і деструктори

Проте в приведеному прикладі не вирішена важлива проблема: функції Alloc і Free як і раніше треба викликати вручну. Інша проблема даного прикладу — небезпека оператора присвоєння. Для вирішення цих проблем в мову були введені конструктори і деструктори. Конструктор викликається кожного разу, коли створюється об'єкт даного типу; деструктор — при знищенні. При перетвореннях типів, присвоєнні, передачі параметра теж викликаються конструктори і при необхідності деструктори.

З конструкторами і деструкторами клас виглядає так:

class Array {
public:
Array() : len(0), val(NULL) {}
Array(int _len) : len(_len) {val = new double[_len];}
Array(const Array& a);
~Array() { Free(); }
inline double Elem(int i);
inline void ChangeElem(int i, double x);
protected:
void Alloc(int _len);
void Free();
int len;
double* val;
};

Array::Array(const Array& a) : len(a.len)
{
val = new double[len];
for (int i=0; i<len; i++)
val[i] = a.val[i];
}

Тут Array::Array — конструктор, а Array::~Array — деструктор. Конструктор копіювання (англ. copy constructor) Array::Array(const Array&) викликається при присвоєнні. Тепер об'єкт класу Array не можна зіпсувати: як би ми його не створювали, що б ми не робили, його значення буде коректним, тому що конструктор викликається автоматично. Всі небезпечні операції з вказівниками заховані в захищені функції.

Array a(5); // викликається Array::Array(int)
Array b; // викликається Array::Array()
Array c(a); // викликається Array::Array(const Array&)
Array d=a; // те саме
b=c; // відбувається виклик оператора =
// якщо він не визначений (як в даному випадку), то викликається оператор присвоєння за умовчанням, який
// здійснює побітове копіювання для базових типів і виклик оператора присвоєння для користувача
// як правило, конструктор копій і оператор присвоєння перевизначаються попарно

Оператор new теж викликає конструктори, а delete — деструктори.

За умовчанням, кожен клас має конструктор без параметрів і деструктор. Конструктор без параметрів за умовчанням викликає конструктори всіх елементів, а деструктор — їх деструктори. Інші конструктори за умовчанням не визначені.

Клас може мати скільки завгодно конструкторів (з різними наборами параметрів), але тільки один деструктор (без параметрів).

Інші можливості функцій-членів

Функції-члени можуть бути і операціями:

class Array {

inline double &operator[] (int n);

І далі
Array a(10);

double b = a[5];

Функції-члени (і лише вони) можуть мати описувач const
class Array {

 inline double operator[] (int n) const;

Такі функції не мають права змінювати поля класу (окрім полів, визначених як mutable). Якщо вони намагаються це зробити, компілятор повинен видати повідомлення про помилку.

Успадкування

Для створення класів з доданою функціональністю вводять успадкування. Клас-нащадок має поля і функції-члени базового класу, але не має права звертатися до приватних (private) полів і функцій базового класу. У цьому і полягає різниця між приватними і захищеними членами.

Клас-нащадок може додавати свої поля і функції або перевизначати функції базового класу.

За умовчанням, конструктор нащадка без параметрів викликає конструктор базового класу, а потім конструктори доданих елементів. Деструктор працює в зворотному порядку. Інші конструктори доводиться визначати кожного разу наново. На щастя, це можна зробити викликом конструктора базового класу.

class ArrayWithAdd : public Array {
ArrayWithAdd(int n) : Array(n) {}
ArrayWithAdd() : Array() {}
ArrayWithAdd(const Array& a) : Array(a) {}
void Add(const Array& a);
};

Нащадок — це більш ніж базовий клас, тому він може використовуватися скрізь, де використовується базовий клас, але не навпаки.

Успадкування буває публічним, захищеним і власним. При публічному спадкуванні, публічні і захищені члени базового класу зберігають свій статус, а до приватних не можуть звертатися навіть функції-члени нащадка. Захищене спадкування відрізняється тим, що при нім публічні члени базового класу є захищеними членами нащадка. При приватному успадкуванні, до жодного члена базового класу навіть функції-члени нащадка права звертатися не мають. Як правило, публічне спадкування зустрічається значно частіше за інші.

Клас може бути нащадком декількох класів. Це називається множинним спадкуванням. Такий клас володіє полями і функціями-членами всіх його предків. Наприклад, клас FlyingCat може бути нащадком класів Cat і FlyingAnimal.

class Cat {
...
void Purr();
...
};
class FlyingAnimal {
...
void Fly();
...
};
class FlyingCat : public Cat, public FlyingAnimal {
...
PurrAndFly() {Purr(); Fly();}
...
};

Поліморфізм

Поліморфізмом в програмуванні називається перевизначення нащадком функцій-членів базового класу, наприклад

class Figure {
...
void Draw() const;
...
};

class Square : public Figure {
...
void Draw() const;
...
};

class Circle : public Figure {
...
void Draw() const;
...
};

В даному прикладі, яка з функцій буде викликана — Circle::Draw(), Square::Draw() або Figure::Draw(), визначається під час компіляції. Наприклад, якщо написати

Figure* x = new Circle(0,0,5);
x->Draw();
то буде викликане Figure::Draw(), оскільки x — об'єкт класу Figure. Такий поліморфізм називається статичним.

Але в C++ є і динамічний поліморфізм, коли функція, що викликається, визначається під час виконання. Для цього функції-члени повинні бути віртуальними.

class Figure {
...
virtual void Draw() const;
...
};

class Square : public Figure {
...
virtual void Draw() const;
...
};

class Circle : public Figure {
...
virtual void Draw() const;
...
};

Figure* figures[10];
figures[0] = new Square(1, 2, 10);
figures[1] = new Circle(3, 5, 8);

for (int i = 0; i < 10; i++)
figures[i]->Draw();

В цьому випадку для кожного елементу буде викликана Square::Draw() або Circle::Draw() залежно від виду фігури.

Чисто віртуальною функцією називається функція-член, яка не визначена в базовому класі, а тільки в нащадках:

class Figure {
...
virtual void Draw() const = 0;
);

Ось це = 0 і означає, що функція чисто віртуальна.

Абстрактним класом називається такий, у якого є хоч би одна чисто віртуальна функція-член. Об'єкти таких класів створювати заборонено. Абстрактні класи використовуються як інтерфейси.

Друзі

Функції-друзі — це функції, що не є функціями-членами, проте мають доступ до захищених і власних полів і функцій-членів класу. Вони повинні бути описані в тілі класу як friend. Наприклад:

class Matrix {
...
friend Matrix Multiply (Matrix m1, Matrix m2);
...
};
Matrix Multiply (Matrix m1, Matrix m2) {
...
}

Тут функція Multiply може звертатися до будь-яких полів і функцій-членів класу Matrix.

Існують також класи-друзі. Якщо клас A — друг класу B, то всі його функції-члени можуть звертатися до будь-яких полів і функцій членів класу B. Наприклад:

class Matrix {
...
friend class Vector;
...
};

Проте в С++ не діє правило «друг мого друга — мій друг».

За стандартом C++03 вкладений клас не має прав доступу до закритих членів охоплюючого класу і не може бути оголошений його другом (це виходить з визначення терміну друг як нечлена класу). Проте, багато розповсюджених компіляторів порушують обидва ці правила (може, зважаючи на сукупну дивність цих правил).

Переглядів: 123

Коментарі

Коментар добавив-(ла): Pidut
Дата: 2010-06-22

Ти придурок. Дуже "цікаво"))) Писати навчися спочатку!!! "друг як нечлена класу"

Добавити коментар



Доведіть що ви не бот, введіть суму чисел на зображенні