рефераты конспекты курсовые дипломные лекции шпоры

Реферат Курсовая Конспект

Переваги спадкування

Переваги спадкування - Конспект, раздел Образование, Конспект лекцій СИСТЕМНЕ ПРОГРАМУВАННЯ Як Випливає З Приведених Вище Простих Прикладів, Спадкування Дозволяє Повторн...

Як випливає з приведених вище простих прикладів, спадкування дозволяє повторно використовувати створені раніше фрагменти програм і структури даних. Це дозволяє уникнути непотрібного дублювання програмного коду.

Перевага спадкування також полягає в спрощенні налагодження і супроводу програм, оскільки код і дані, що управляють виконанням завдання, не розсіяні, а містяться в одному, легко визначуваному місці програми.

У мові C++ за допомогою ієрархії класів можна відтворити модель взаємин реального світу. Наприклад, при створенні класу CWindow, похідного від CFrame, відображається той факт, що вікно є прямокутником визначеного типу (прямокутником, внутрішня область якого залита кольором), а створення класу CRoundWind, похідного від CWindow, відповідає тому, що закруглене вікно є різновидом вікна іншого типу.

7.2.8 Приклади бібліотек класів і множинне спадкування

Такі комерційні бібліотеки класів, як MFC (бібліотека фундаментальних класів фірми Microsoft) та iostream (стандартна бібліотека вводу-виводу мови C++), містять переважно деревовидні ієрархії споріднених класів. В таких ієрархіях один клас зазвичай служить базовим для декількох похідних, що і породжує деревовидну структуру. Названі бібліотеки класів включені в систему програмування Visual C++.

Ієрархія класів бібліотеки MFC ретельно моделює взаємозв'язки між різними елементами операційної системи Windows, є візуальною основою системи програмування Visual C++ і використовується при розробці комплексних застосувань для Windows.

Бібліотека iostream здійснює об'єктно-орієнтований потоковий ввід-вивід програм на мові C++ і забезпечує, зокрема, засоби форматного вводу-виводу, підтримку маніпуляторів вводу-виводу, а також створення функцій вводу-виводу користувача.

Тоді як в бібліотеці MFC використовуються чисто деревовидні структури, в бібліотеці iostream використовується спадкування, коли один клас є похідним більше ніж від одного класу. Таке спадкування називається множинним спадкуванням (multiple inheritance).

7.3 Віртуальні функції. Поліморфізм

Віртуальні функції дозволяють писати прості універсальні підпрограми для маніпулювання об'єктами різних типів. Вони дають можливість змінювати властивості існуючих базових класів навіть за відсутності доступу до початкового коду цих класів.

7.3.1 Вказівники на базові класи

У мові C++ допускається присвоювати адресу об'єкту похідного класу вказівнику на базовий клас, оскільки його використання в такому контексті цілком коректно.

Вказівник на базовий клас використовується для доступу до членів, оголошених тільки в базовому класі. Всі вони також визначені всередині похідного класу шляхом спадкування. Отже, якщо вказівник містить адресу об'єкту похідного класу, то можна отримати значення будь-якого члена об’єкту класу, на який задано посилання за допомогою вказівника.

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

7.3.2 Віртуальні функції

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

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

Для розуміння концепції віртуальних функцій порівняємо ще раз приведені вище класи CFrame і CWindow. Клас CWindow є похідним від CFrame. Отже, CFrame - базовий по відношенню до CWindow. Обидва цих класи містять функцію Draw(). Припустимо, що оголошені об'єкти обох класів:

 

CFrame Frm;

CWindow Wind;

 

Після таких оголошень версію функції Draw(), визначену в класі CFrame, викликатиме інструкція:

 

Frm.Draw();

 

а версію функції Draw(), визначену в рамках CWindow, викликатиме інструкція:

 

Wind.Draw();

 

В обох випадках компілятор без проблем визначає, яка версія функції викликається, оскільки виклик функції містить посилання на об'єкт класу.

Проте в мові C++ прийнято використовувати вказівник на базовий клас, що містить або адресу об'єкту базового, або адресу об'єкту похідного класу.

Наприклад, розглянемо наступний вказівник на клас CFrame:

 

CFrame *PFrm;

 

У C++ дозволяється присвоювати цьому вказівнику адресу як об'єкту класу CFrame, так і об'єкту класу, прямо або побічно похідного від CFrame, без приведення типів.

Наприклад, в показаному нижче фрагменті програми в останніх двох інструкціях допустимі обидва присвоювання:

 

CFrame *PFrm; // оголошується вказівник на клас CFrame

CFrame Frm; // створюється об'єкт класу CFrame

CWindow Wind; // створюється об'єкт класу CWindow

PFrm = &Frm; // допустимо - присвоюється вказівнику адреса

// об'єкту CFrame

PFrm = &Wind; // також допустимо - присвоюється вказівнику

// адреса об'єкту CWindow

 

Якщо для виклику функції Draw() використовується вказівник PFrm, може виникнути проблема. Компілятор не може визначити наперед, на який тип об'єкту указує PFrm, поки програма не почне виконуватися. Тому компілятор завжди генерує виклик версії Draw(), визначеної в класі CFrame, оскільки вказівник PFrm оголошений як вказівник на CFrame.

Припустимо, вказівник PFrm містить адресу об'єкту Frm, що є екземпляром класу CFrame:

 

CFrame *PFrm;

CFrame Frm;

// …

PFrm = &Frm;

В даному випадку застосування вказівника PFrm при виклику функції-члена Draw() ініціюватиме виклик версії Draw(), визначеної в класі CFrame:

 

PFrm->Draw(); // генерується виклик функції Draw() класу CFrame

 

Припустимо тепер, що вказівник PFrm містить адресу об'єкту класу CWindow:

 

CFrame *PFrm;

CWindow Wind;

// ...

PFrm = &Wind;

 

При використанні цього вказівника для виклику функції-члена Draw() програма як і раніше викликатиме версію Draw(), визначену в класі CFrame:

 

PFrm->Draw(); // генерується виклик все тієї ж функції Draw()

// класу CFrame

 

В результаті виходить виклик неправильної версії функції Draw(), що створює прозорий, а не закрашений прямокутник.

Рішенням цієї проблеми може бути перетворення Draw() у віртуальну функцію.

Оголошення Draw() як віртуальної функції гарантує, що при запуску програми буде викликана коректна версія функції, навіть якщо виклик здійснюватиметься через вказівник базового класу. Щоб задати функцію Draw() як віртуальну, потрібно включити специфікатор virtual в оголошення цієї функції в базовому класі CFrame:

 

class CFrame

{

// інші оголошення

public:

virtual void Draw ();

// інші оголошення

};

 

Специфікатор virtual не можна включати у визначення функції Draw(), що знаходиться поза оголошенням класу.

Специфікатор virtual можна включити і в оголошення функції Draw() у похідному класі CWindow, хоча в цьому і немає необхідності:

 

class CWindow : public CFrame

{

// інші оголошення

public:

virtual void Draw ();

// інші оголошення

};

 

Якщо функціяоголошена в базовому класі як віртуальна, то функція з таким же ім'ям, типом значення, що повертається, і аргументами, оголошена в похідному класі, автоматично розглядається як віртуальна. Отже, немає необхідності повторювати специфікатор virtual у кожному похідному класі, хоча таке повторення іноді полегшує читання програми.

Якщо функціяDraw() оголошена як віртуальна і програма викликає її через вказівник PFrm, як показано нижче, компілятор не генеруватиме виклик версії Draw(), оголошеної у класі CFrame:

 

CFrame *PFrm;

// …

PFrm->Draw();

 

Натомість компілятор створює спеціальний код, що викликає в процесі виконання програми правильну версію функції Draw(), відповідну класу об'єкту, адреса якого в момент виклику міститься у вказівнику.

Таким чином, наступні інструкції приведуть до виклику функції Draw(), оголошеної в класі CFrame:

 

CFrame *PFrm;

CFrame Frm;

PFrm = &Frm;

PFrm->Draw (); // спеціальний код викликає функцію Draw()

// класу CFrame

 

У цьому фрагменті викликається функціяDraw() класу CWindow:

 

CFrame *PFrm;

CWindow Wind;

PFrm = &Wind;

PFrm->Draw(); // спеціальний код викликає функцію Draw()

// класу CWindow

 

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

Окрім додаткового об'єму пам'яті, динамічний виклик вимагає непрямого виклику функції (виклику функції через вказівник), що приводить до повільнішої роботи у порівнянні з викликом стандартних функцій. Тому в класі рекомендується робити функцію-член| віртуальною тільки тоді, коли потрібно дійсно пізнє зв'язування.

7.3.3 Поліморфізм

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

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

Приклад поліморфізму — виклик однієї і тієї ж функції:

 

PFrm->Draw();

 

для малювання прямокутників, вікон і вікон із закругленими кутами. Дія, що виконується у кожному конкретному випадку, визначається класом об'єкту, який в даний момент адресує вказівник PFrm.

7.3.4 Застосування віртуальних функцій для управління об'єктами різних класів

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

Припустимо, є програма, що дозволяє створювати прямокутники, вікна або вікна із закругленими кутами. Кожного разу, коли користувач створює одну з цих фігур, програма викликає нову інструкцію для динамічного створення об'єкту відповідного класу (CFrame, CWindow або CRoundWind), управляючого новою фігурою. Оскільки класи CWindow та CRoundWind є похідними від класу CFrame, то вказівники на всі об'єкти зручно зберігати у вигляді одновимірного масиву вказівників на базовий клас CFrame. Це показано в наступному фрагменті програми:

 

const int MAXFIGS = 100;

CFrame *PFigure[MAXFIGS];

int Count = 0;

// ...

// створюється вікно:

PFigure [Count++] = new CWindow (10, 15, 25, 30, 5);

// ...

// створюється прямокутник:

PFigure [Count++] = new CFrame(5, 8, 19, 23);

// ...

// створюється вікно із закругленими кутами:

PFigure [Count++] = new CRoundWind(27, 33, 43, 56, 10, 5);

 

Тепер припустимо, що є підпрограма перемальовування всіх об'єктів на екрані. Якщо функціяDraw() не оголошена як віртуальна, то для кожного елементу масиву необхідно якимось чином визначити тип фігури, а потім викликати відповідну версію функції Draw(). Наприклад, в клас CFrame можна додати змінну з ім'ям Туре, в якій зберігатиметься код, що ідентифікує клас об'єкту:

 

class CFrame

{

// інші оголошення

public:

int Type; // успадковується всіма похідними класами,

// зберігає код, що ідентифікує клас об'єкту:

// FRM, WIND, або ROUNDWIND

};

 

В даному прикладі передбачається, що три іменовані літерали FRM, WIND та ROUNDWIND були оголошені в програмі заздалегідь.

Змінну Турe можна використовувати для визначення типу кожної з фігур масиву, щоб викликати відповідну версію функції Draw():

 

for (int i = 0; i < Count; ++i)

switch (PFigure[i]->Type)

{

case FRM:

PFigure[i]->Draw();

break;

case WIND:

((CWindow *)PFigure[i])->Draw();

break;

case ROUNDWIND:

((CRoundWind *)PFigure[i])->Draw();

break;

}

 

Цей приклад вимагає додавання нової гілки case в інструкцію вибору switch при розширенні програми для підтримки нового типу фігур (наприклад, при додаванні в ієрархію нового класу для управління новою фігурою, такою як заштрихований прямокутник).

Якщо ж зробити функцію Draw() віртуальною, додавши специфікатор virtual в її оголошення всередині класу CFrame, програма автоматично викличе правильну версію функції для поточного типу об'єкту. Тоді перемальовування всіх фігур може бути виконане за допомогою наступного фрагменту програми:

 

for (int i = 0; i < Count; ++i)

PFigure[i]->Draw();

Цей код істотно простіший і компактніший|. До того ж він не вимагає змін при додаванні в ієрархію нового класу, що підтримує фігури іншого типу.

7.3.5 Застосування віртуальних функцій для модифікації базових класів

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

 

class CMessageBox

{

protected:

char *Message;

virtual void DrawBackground (int L, int T, int R, int B);

// закрашує фон вікна повідомлень в білий колір

public:

CMessageBox()

{

Message = new char (' 0‘);

}

~CMessageBox()

{

delete[] Message;

}

void Display()

{

DrawBackground(0, 0, 35, 25);

// інструкції для виводу рядка повідомлення

}

void Set(char *Msg);

};

 

Відкрита функція-член Set() дозволяє встановити рядок повідомлення, а функція Display() виводить це повідомлення на екран.

Функція Display() очищує фон, викликаючи іншу функцію-член DrawBackground() і передаючи їй розміри вікна повідомлення. Функція DrawBackground() закрашує фон, використовуючи непрозорий білий колір. Функція DrawBackground() призначена для використання всередині класу. Вона не призначена для виклику ззовні класу і, отже, оголошена як захищений член класу.

Функція DrawBackground() оголошена також віртуальною. Відповідно, при породженні від класу CMessageBox нового класу, що містить власну версію DrawBackGround(), нова функціяперекриє стару, навіть якщо викликатиметься з функції-члена класу CMessageBox().

Наприклад, від класу CMessageBox можна породити наступний клас:

 

class CMyMessageBox:public CMessageBox

{

protected:

virtual void DrawBackground (int L, int T, int R, int B)

{

// закрашує фон вікна повідомлення синім кольором

}

};

 

Оскільки нова версія функції DrawBackground() створює синій фон, а не білий, в приведеному нижче фрагменті буде створено вікно повідомлення з синім фоном:

 

CMyMessageBox MyMessageBox;

MyMessageBox.Set ("hello");

MyMessageBox.Display ();

 

Роблячи функцію DrawBackground() віртуальною, ми отримуємо можливість настроювати клас CMessageBox (а саме колір або узор, яким заповнюється фон вікна повідомлення) без модифікації початкового тексту даного класу. При цьому навіть не потрібно проглядати початковий програмний код.

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

7.3.6 Механізм перевизначення базових класів

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

Посилання на член класу з функції-члена неявно зв'язано із застосуванням вказівника this. Таким чином, функцію Display() класу CMessageBox можна записати так:

 

class CMessageBox

{

// інші визначення

public:

void Display ()

{

this->DrawBackground(0, 0, 35, 25);

// …

}

// інші визначення

};

 

Якби функціяDrawBackground() не була віртуальною, то її виклик з функції Display() ініціював би виклик версії DrawBackground() класу CMessageBox, оскільки в межах цього класу вказівник this є вказівником на об'єкт класу CMessageBox. Проте якщо функція DrawBackground() є віртуальною, її виклик ініціалізує виклик версії DrawBackground() класу поточного об'єкту. Таким чином, якщо функція Display() викликана для об'єкту класу CMyMessageBox, то буде викликана і DrawBackground(), визначена усередині цього класу:

 

CMyMessageBox MyMessagBox;

// …

MyMessageBox.Display();

7.3.7 Конкретні й абстрактні класи

Багато класів схожі з класом CFrame тим, що в них можна дати розумне визначення віртуальних функцій, якщо вони є, і тим, що об'єкти таких класів можна оголошувати.

Класи, об'єкти яких можуть бути оголошені та реалізовані, називаються конкретними класами.

Проте є інші класи. Деякі, наприклад, такі як показаний нижче клас абстрактної фігури CShape, представляють собою абстрактні поняття, для яких не можна створювати об'єкти.

Абстрактний клас CShape набуває сенсу тільки як базовий клас для деяких похідних класів. Причиною є те, що неможливо дати осмислене визначення віртуальних функцій класу CShape:

 

class CShape

{

// ...

public:

// не можна ні обертати, ні малювати абстрактну фігуру

virtual void rotate(int){error("CShape::rotate"); }

virtual void draw(){error("CShape::draw"); }

// ...

};

 

Створення об'єкту класу CShape (абстрактної фігури) - законна, хоча абсолютно безглузда операція:

 

CShape s; // позбавлено сенсу

 

Вона безглузда тому, що будь-яка операція з об'єктом s приведе до видачі повідомлення про помилку.

В таких випадках краще віртуальні функції класу CShape оголосити як чисто віртуальні. Зробити віртуальну функцію чисто віртуальною можна, додавши в кінці її оголошення ініціалізатор "= 0":

 

class CShape

{

// ...

public:

virtual void rotate(int) = 0; // чисто віртуальна функція

virtual void draw() = 0; // чисто віртуальна функція

};

 

Чисто віртуальною функцією називається віртуальна функція, в оголошенні якої її тіло визначено як 0, тобто його не можна визначити в рамках базового класу.

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

Об'єкти абстрактного класу створювати не можна, оскільки він має нереалізовані функції:

 

CShape s; // помилка: змінна абстрактного класу CShape

 

Абстрактний клас можна використовувати тільки як базовий при створенні іншого класу:

 

class Circle : public CShape

{

int radius;

public:

void rotate(int){} // нормально - перевизначення CShape::rotate()

void draw(); // нормально – повторне оголошення CShape::draw()

Circle(point p, int r);

};

 

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

 

class X

{

public:

virtual void f() = 0;

virtual void g() = 0;

};

X b; // помилка - оголошення об'єкту абстрактного класу X

class Y : public X

{

void f(); // повторне оголошення X::f()

// клас залишається абстрактним, оскільки X::g() не перевизначена

};

Y b; // помилка - оголошення об'єкту абстрактного класу Y

class Z : public Y

{

void g(); // повторне оголошення X::g()

};

Z c; // нормально – обидві функції перевизначені

 

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

 

class Character_device

{

public:

virtual int open() = 0;

virtual int close(const char*)= 0;

virtual int read(const char*, int)=0;

virtual int write(const char*, int)= 0;

virtual int ioctl(int ...)= 0;

virtual ~Character_device(){} // віртуальний деструктор

};

 

Справжні драйвери будуть оголошуватися як класи, похідні від класу Character_device, і управлятися за допомогою приведеного абстрактного інтерфейсу.

7.3.8 Внутрішня реалізація віртуальних функцій та поліморфізму

Для реалізації віртуальних функцій та поліморфізму компілятори користуються технологією перетворення імені віртуальної функції в індекс в таблиці, що містить вказівники на функції. Така таблиця є одновимірним масивом вказівників на функції і називається таблицею віртуальних функцій (virtual function table – vtbl).

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

Для базового класу Character_device таблицю віртуальних функцій можна представити графічно так, як це показано на мал. 7.1.

open
close
read
write
ioctl
~Character_device

 

Малюнок 7.1 Таблиця віртуальних функцій

 

Таблиця vtbl містить вказівники на віртуальні функції класу, імена яких вказані у відповідних комірках на малюнку. Зліва від комірок з іменами функцій вказані номери цих функцій в таблиці vtbl .

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

Для кожного похідного класу робиться копія таблиці vtbl його прямого базового класу. При цьому для перевизначених у похідному класі віртуальних функцій нульові вказівники в комірках vtbl заміщаються вказівниками на реалізації відповідних функцій.

Кожен об'єкт базового або похідного класу з віртуальними функціями міститься в своїй ділянці пам'яті, і в пам'яті кожного об'єкту є посилання на загальну для всіх об'єктів цього класу таблицю vtbl:

 

  Об'єкт 1       Об'єкт 2  
-4 Вказівник vtbl -> Vtbl класу <- Вказівник vtbl -4
    open    
      close      
      read      
      write      
      ioctl      
      ~Character_device      

 

Малюнок 7.2 Взаємозв'язок об'єктів з таблицею віртуальних функцій

 

При виклику віртуальної функції через вказівник на об'єкт базового класу (поліморфізм) з пам'яті об'єкту із віддаленням в -4 по відношенню до значення вказівника здійснюється вибірка вказівника (базової адреси) таблиці віртуальних функцій класу – vtbl. Після цього вказівник на vtbl індексується номером віртуальної функції, з елементу таблиці вибирається вказівник на відповідну номеру віртуальну функцію, після чого здійснюється непрямий виклик функції через вказівник.

Оскільки в базовому і похідному класах вказівники на віртуальні функції завжди знаходяться в одних і тих же по номеру елементах vtbl, завжди викликається реалізація віртуальної функції, відповідна класу об'єкту.

7.4 Перевантаження операторів

До даних вбудованих типів оператори C++ застосовуються наперед визначеним способом.

Наприклад, при використанні оператора складання до двох змінних типу int виконується цілочисельне складання, а при використанні оператора "+" для двох змінних типу double - операція складання з плаваючою крапкою. У мові C++ допустимо застосування стандартних операторів до об'єктів класів за умови точного опису їх дії.

Визначення способу роботи операторів з об'єктами конкретного класу називається перевантаженням (overloading) операторів.

– Конец работы –

Эта тема принадлежит разделу:

Конспект лекцій СИСТЕМНЕ ПРОГРАМУВАННЯ

Конспект лекцій... по дисциплiні СИСТЕМНЕ ПРОГРАМУВАННЯ...

Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Переваги спадкування

Что будем делать с полученным материалом:

Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:

Все темы данного раздела:

РОБОТА З ДАНИМИ
Якість організації і представлення даних, що обробляються програмами, має не менше значення, ніж хороше розбиття програм на функції, обробляючі ці дані, та реалізація алгоритмів цих функцій. Більш

Оголошення
В мові С++ кожне ім'я (ідентифікатор) слід оголосити перш, ніж воно буде використовуватися в програмі. Це означає, що потрібно вказати його тип, щоб компілятор знав, до якого виду об'єктів має відн

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

Посилання
Посилання (reference) – особливий тип даних, що є прихованою формою вказівника, який при зверненні автоматично розіменовується. Посилання можна розглядати як ще одне ім'я об'єкту. Посиланн

Типи даних користувача
Описані раніше вбудовані типи даних мови C++ можуть бути доповнені новими типами даних, визначеними самим користувачем. Типи даних користувача діляться на три групи: переліки, структури й об'єднанн

Структури мови C
Масив є сукупністю елементів одного типу, а структура є сукупністю елементів різних типів. Оголошення структури має наступний формат:   struct struct_name {

Оголошення typedef
Оголошення, що починається з ключового слова typedef, вводить нове ім'я (синонім) для типу, а не оголошує нову змінну цього типу. Формат оголошення typedef наступний:   typed

Масиви як аргументи
Якщо в якості аргументу функції задається масив, то передається вказівник на його перший елемент. Наприклад:   int strlen(const char*); void f() {

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

Макрос WINAPI
Оскільки компілятор Visual C++ більше не підтримує ключових слів __pascal, __fortran та __syscall, їх дію рекомендується емулювати за допомогою описаних вище ключових слів __cdecl, __stdcall або __

ПРОГРАМУВАННЯ ВИКЛЮЧЕНЬ
Виключною ситуацією, або виключенням (exception), називається переривання нормального потоку виконання програми у відповідь на непередбачену або аварійну подію. Події, що приводять до викл

Виключення Win32
Разом з програмними викликами виключень за допомогою інструкції throw, виключення генеруються системними програмами Win32 API у відповідь на збій апаратного або програмного забезпечення. Такі виклю

Обробка виключень Win32
Існує декілька способів обробки виключень Win32. Найбільш простий з них полягає в використанні блоку catch з трьома крапками:   try { // … // генер

МОДУЛЬНЕ ПРОГРАМУВАННЯ
Набір зв'язаних процедур разом з даними, які вони обробляють, називається модулем. Модуль – програмний фрагмент, який є будівельним блоком для побудови великих програм. Як правило, модуль складаєть

Директиви препроцесора
Існує 14 стандартних директив препроцесора:   #include #define #undef #if #ifdef #ifndef #elif #else #

Макроси
Директива #define для оголошення макросів має дві синтаксичні форми:   #define ідентифікатор макроозначення #define ідентифікатор (список параметрів) макроозначення

Конструктори
Раніше наведене оголошення класу CFrame дозволяє ініціалізувати змінні-члени об'єктів класу шляхом виклику програмою користувача функції-члена класу SetCoord(). В якості іншого, стандартно

Конструктори за умовчанням
Конструктор без аргументів називають конструктором за умовчанням. Такий конструктор звичайно ініціалізує змінні-члени, присвоюючи їм стандартні, встановлювані за умовчанням значення. Наприклад, нас

Деструктори
Відповідно до принципів об'єктно-орієнтованого програмування| в класі можна оголосити спеціальну функцію-член|, звану деструктором. Деструктор автоматично викликається кожного разу при зни

Правила спадкування
Спадкування, тобто породження одного класу з іншого, дозволяє повторно використовувати коди й структури даних, раніше створені для інших класів. Це робить програму зрозумілішою і допомагає в моделю

Конструктори приведення
Конструктор приведення класу — це конструктор з єдиним аргументом, тип якого відрізняється від типу класу. Такий конструктор звичайно ініціалізує новий об'єкт, використовуючи літерали, або дані змі

УЗАГАЛЬНЕНЕ ПРОГРАМУВАННЯ
Узагальнене програмування з використанням шаблонів мови C++ полегшує генерацію сімейств функцій або класів, що оперують множинами даних різних типів. При цьому не виникає необхідності створювати ок

Клас string
У мові C++ для представлення і обробки рядків є дві можливості. По-перше, можна використовувати символьний масив, що закінчується нулем і є рядком в стилі мови C, як це й робилося практичн

Контейнери
Перед тим, як дати загальне визначення контейнера, спочатку як приклад сконструюємо простий контейнер на базі розглянутого раніше стека символів. Ми можемо узагальнити стек символів до сте

Потоки вводу - виводу
Як вже мовилося раніше, якщо програма на мові C починає виконуватися, автоматично відкриваються три потоки: stdin, stdout і stderr.Щось схоже має місце при завантаженні програми, написаної на мові

Класи потокового вводу - виводу
У C++ ввід - вивід забезпечується підключенням до програми заголовного файлу <iostream>. Саме в цьому файлі оголошені класи, що підтримують операції вводу – виводу. Система вводу – в

Прапори формату
Кожен потік вводу - виводу пов'язаний з набором прапорів формату (format flags), які управляють способом форматування інформації і є бітовими масками. Ці маски оголошені в класі ios як дані перелік

Закриття файлу
Для закриття файлу використовується функція-член| close(). Наприклад, щоб закрити файл, пов'язаний з потоком mystream, необхідна наступна інструкція:   mystream.close ();

Контроль стану вводу - виводу
В системі вводу - виводу C++ підтримується інформація про стан після кожної операції вводу - виводу. Поточний стан потоку вводу - виводу, який зберігається в об'єкті типу iostate, є переліком, визн

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

Мова програмування Visual Basic .NET
Хоча мови програмування керований C++, С# та Visual Basic .NET (VB) семантично мають практично однакові можливості, оскільки всі вони базуються на загальній специфікації мов програмування .NET (CLS

Цикл For
В мові С++ цикл for має дещо інший синтаксис, ніж цикл For в мові VB, але концепція залишається тою ж самою, якщо не зважати на те, що операція, яка виконується в кінці кожної ітерації, має бути вк

Хотите получать на электронную почту самые свежие новости?
Education Insider Sample
Подпишитесь на Нашу рассылку
Наша политика приватности обеспечивает 100% безопасность и анонимность Ваших E-Mail
Реклама
Соответствующий теме материал
  • Похожее
  • Популярное
  • Облако тегов
  • Здесь
  • Временно
  • Пусто
Теги