ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Об'єктивне програмування
         

     

    Інформатика, програмування

    Введення в об'єктно ПРОГРАМУВАННЯ

    Лекція 1. Об'єктне програмування як технологія програмування
    -------------------------------------------------- -----------

    Традиційна технологія програмування 70-х років - структурнийпрограмування:

    - модульне програмування;

    - спадний програмування;

    - структурний проектування процедур і даних (програмування безgoto).

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

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

    Наступний крок - введення в програму об'єктів. Під об'єктомрозуміється структура даних, яка містить повну інформацію про станвідповідного фізичного об'єкта, що відображається програмою. У
    Сі цьому може відповідати структура struct), у Паскалі - запис
    (record). Безліч об'єктів одного типу складають поняття класу.
    Об'єктно-орієнтований підхід до розробки програм припускає, що впрограмі встановлюється взаємно-однозначна відповідність міжфізичними об'єктами,відображаються програмою, і програмними об'єктами, які є, посуті, структурованими змінними (надалі під терміном
    "об'єкт" будемо розуміти програмний об'єкт).

    Традиційний підхід: ---------- мінлива тип даних

    Об'єктно-орієнтир-фізичний програмний класний підхід: об'єкт об'єкт об'єктів

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

    Об'єктно-орієнтовані програми можна розробляти і за допомогоютрадиційних мов програмування. Розглянемо приклад визначенняоб'єктів типу "дата" на класичному Сі.

    //------ структура dat - аналог класу об'єктів "дата" -------- typedefstruct dat

    (unsigned day; unsigned month; unsigned year;

    )

    DAT;
    //----- Набір функцій для класу об'єктів "дата" -------------- static int mm [] = (31,28,31,30,31,30,31, 31,30,31,30,31);
    //----- Перевірка на коректність ----------------------------- int
    TestData (p)
    DAT * p;
    (if (p-> month == 2 & & p-> day == 29 & & p-> year% 4 == 0) return (1);if (p-> month == 0 | | p-> month> 12 | | p-> day == 0 | | p-> day> mm [p-> month]) return (0);return (1);
    )
    //------ Наступна дата ---------------------------------------- void
    NextData (p)
    DAT * p;
    (p-> day + +;if (p-> day month]) return;if (p-> month == 2 & & p-> day == 29 & & p-> year% 4 == 0) return;p-> day = 1;p-> month + +;if (p-> month! = 13) return;p-> month = 1;p-> year + +;
    )
    //------- Наступна дата через n днів -------------------------- void
    PlusData (p, n)
    DAT * p;int n;
    (while (n -! = 0) NextData (p);
    )
    //------- Основна програма ---------------------------------void main ()
    (
    DAT a;do

    (scanf ( "% d% d% d", & a.day, & a.month, & a.year);

    )while (TestData (& a) == 0);
    PlusData (& a, 17);
    )
    //------------------------------------------------ --------

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

    Мова програмування Сі + + є розширення мови Сідля програмування об'єктів та їх класів. При цьому використаннякласів еквівалентно аж до синтаксису використання базових типівданих:

    Поняття класичного Сі Поняття Сі + +

    ------------------------- -- --------- БТД:

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

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

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

    Лекція 2. Додаткові можливості мови Сі + +

    ------------------------------------- ----------

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

    2.1. Присвоєння структур

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

    struct dat

    (int day, month, year;)

    dat NextDat (dat x)// Формальний параметр - структура
    (... return (x);)// Повернути структуру як результат

    dat Nextdat1 (dat * p)
    (... return (* p);)// Повернення структури побічно за посиланням

    dat a, b, c, * q;// Ключове слово struct не використовуєтьсяvoid main ()
    (q = &b;a = b;// Пряме присвоєння структурa = * q;// Непряме присвоювання за посиланнямc = NextDat (b);// Присвоєння структури як результатуc = NextDat1 (& b);// функції, фактичний параметр у
    )// NextDat - копія структури

    2.2. Звернення за адресою (неявна посилання)

    ------------------------------------ ----

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

    Сі + + Еквівалент в "класичному" Сі
    ------------------------ -------------------------- ---//-------------< br>- Ініціалізація константою ----------------- int & a = 5; int a, * pa = a;

    * pa = 5;
    //--------------- Ініціалізація змінної ----------------- int x; int x, * pa;int & a = x; pa = &x;

    a = 5; * pa = 5;
    //-------------- Неявна посилання на структуру ---------------- struct dat struct dat
    (Int day, month, year); (int day, month, year);dat x; dat x;dat & b = x; dat * pb = &x;dat & c = (12,12,1990); dat cc = (12,12,1990); dat * pc = &cc;

    b.year = 1990; pb-> year = 1990;c.day = b.day 3; pc-> day = pb-> day 3;c = b;// Копіювання pc-> day = pb-> day;

    // структури pc-> month = pb-> month; pc-> year = pb-> year;

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

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

    - значенням;

    - явною посиланням;

    - неявної посиланням.

    Приклад 1. Параметри - значення
    -------------------------------------------------- ------- dat Inc (dat x)

    ========> - копіювання
    (--------> - Посиланняx.day + +;return (x); ----¬ стек +---+ x.day + +
    ) | B =========> x =========¬

    L ---- +---+ | return (x)void main () |
    (----¬ Стек +---+ --|-¬ тимчасоваdat a, b, * p; | a day + +x-> day + +; ----¬ стек +---+return (x); г ===== b |a = * Inc (Inc (& b)); | | L ---- +-|-+p = Inc (& b); | | ----¬ | return (x)a = * p; | L - a |

    L ---
    Приклад 3. Параметри - неявні посилання
    -------------------------------------------------- ------- dat & Inc (dat &x) x.day + + неявна посилання dat * px
    (X.day + +x.day + +; ----¬ стек +---+return (x); г ===== b |a = Inc (Inc (b)); | | L ---- +-|-+p = & Inc (b); | | ----¬ | return (px)a = * p; | L - a |

    L ---

    Порівняння цих прикладів показує наступне:

    - при роботі з формальним параметром - неявної посиланнямвикористовується ім'я формального параметра в якості ідентифікаторазмінної, яка замінюється транслятором на непряме звернення знеявної посиланням;

    - при поверненні результату використовується ім'я змінної, яказамінюється транслятором неявної посиланням на неї;

    - приклади 2 і 3 ідентичні з реалізації, але відрізняються засинтаксису виклику функції;

    - приклади 1 і 3 відрізняються по реалізації, але ідентичні засинтаксису виклику функції;

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

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

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

    - при виконанні операції return (x), де x - локальна змінна абоформальний параметр, виконується побайтовое копіювання змінної x задресою, заданому неявним параметром;

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

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

    Програма на Сі + + Реалізація
    ----------------- ---------- - Неявний параметрdat Inc (dat x) void Inc (dat * r, dat x)
    ((x.day + +; x.day + +;return (x); * r = x;// Копіювання
    ))// Результату

    void main () void main ()
    ((dat a, b * p; dat a, b, * p; dat t, u;// Временнye переменнyea = Inc (b); Inc (& a, b);// Посилання на ліву частинуp = & Inc (b); Inc (& t, b);// Прісаіваніе тимчасової p = &t;// змінної та отриманняa = * p; a = * p;// посилання на неїa = Inc (Inc (b)); Inc (& u, b);// Проміжний результат

    Inc (& a, u);// в тимчасовій змінної
    ))

    2.3. Функції - елементи структури

    -------------------------------- Повторимо розглянутий вищеприклад в іншій формі:

    //------------ структура dat - аналог класу об'єктів "Дата" - struct dat

    (unsigned day; unsigned month; unsigned year; int TestData (); void NextData (); void PlusData (int n)

    (while (n -! = 0) dat:: NextData (this);

    )

    );
    //----------- Набір функцій для класу об'єктів "дата" -------- static int mm [] = (31,28,31,30,31,30,31, 31,30,31,30,31);
    //----------- Перевірка на коректність ----------------------- intdat:: TestData ()
    (if (month == 2 & & day == 29 & & year% 4 == 0) return (1);if (month == 0 | | month> 12 | | day == 0 | | day> mm [month]) return (0);return (1);
    )
    //----------- Наступна дата ---------------------------------- voiddat:: NextData ()
    (day + +;if (day month = 5; this-> day ++;

    або неявно

    month = 5; day ++;

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

    . ()

    2.4. Перевизначення функцій

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

    overload SetDat;void SetDat (int dd, int mm, int yy, dat * p)

    (//Дата вводиться у вигляді трьох цілих p-> day = dd; p-> month = mm; p-> year = yy;

    )void SetDat (char * s, dat * p)// Дата вводиться у вигляді рядка

    (sscanf (s, "% d% d% d", & p-> day, & p-> month, & p -> year);

    )

    void main ()

    (dat a, b;

    SetDat (12, 12, 1990, & a);// Виклик перших функції

    SetDat ( "12,12,1990", & b);// Виклик другий функції

    )

    Функції-елементи також можуть бути перевизначені, при цьому явногореклами не потрібно.

    struct dat

    (int day, month, year; void SetDat (int, int, int); void Setdat (char *); < p>)void dat:: SetDat (int dd, int mm, int yy)

    (day = dd; month = mm; year = yy;

    )void dat:: SetDat (char * s)

    (sscanf (s, "% d% d% d", & day, month &, & year);

    )void main ()

    (dat a, b; a.SetDat (12,12,1990); b.SetDat ( "12,12,1990 ");

    )

    2.5. Оператори управління динамічною пам'яттю

    --------------------------------------- ------

    У бібліотеці Сі є дві функції управління динамічною пам'яттю --malloc () і free (), які виділяють і звільняють область пам'ятізаданого розміру (в байтах). У цій області програма може матизмінну (або масив), яка називається динамічною. При виділенніпам'яті під динамічну змінну необхідно за допомогою операції sizeofвизначати кількість байтів, необхідне для розміщення змінноїзазначеного типу. У Сі + + введені два оператори, аналогічні функціям mallocі free new та delete. Вони відрізняються від відповідних функцій тим, щодопускають використання в якості аргументів безпосередньоспецифікацію типу створюваної динамічної змінної та посилання надинамічну змінну:

    Сі + + "Класичний" Сі
    ------------------------- ------------------------- -------- char
    * s, x [80]; char * s, x [80];dat * p, * q; struct dat * p, * q;void main () void main ()
    ((p = new dat; p = malloc (sizeof (struct dat));q = new dat [15]; q = malloc (15 * sizeof (struct dat));gets (x); gets (x);s = new char [strlen (x) +1]; s = malloc (strlen (x) +1);
    ... ...delete p; free (p);delete q; free (q);delete s; free (s);
    )

    Оператори мають вигляд:

    delete

    2.6. Параметри функцій за замовчуванням

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

    //----- Функція встановлює за замовчуванням поточне значення року,
    //----- Місяця і дня
    # include

    void dat:: SetDat (int d = 0, int m = 0, int y = 0)
    (struct date x;getdate (& x);// Стандартна функція отримання

    // поточної дати

    // Перевірка на значення за замовчуваннямyear = (y == 0)? x.da_year: y;month = (m == 0)? x.da_month: m;day = (d == 0)? x.da_day: d;
    )

    2.7 Контроль перетворення типів посилань

    ------------------------------ ---------

    В "класичному" Сі при виконанні привласнення, передачіфактичних параметрів відбувається автоматичне перетворення посилань добазових типів даних (int, unsigned) і навпаки, а також перетворенняодного типу посилання до іншого. У Сі + + такі "вільності" виключені,програміст повинен сам виконати явне перетворення. Наприклад, привикористанні функції розподілу динамічної пам'яті, що має прототип в
    "alloc.h"

    extern void * malloc (int n);

    dat * p;

    p = (dat *) malloc (10 * sizeof (dat ));

    |

    L --- перетворення void * в dat *

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

    2.8 вставляються (inline) функції

    ------------------ -------------

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

    struct dat

    (int d, m, y; void Setdat (char * p)// Функція inline за замовчуванням

    (

    ...// Тіло функції

    )

    2.9 Посилання на елементи структури

    ------------------- ------------

    Якщо структура має кілька елементів одного типу, то для неїможе бути створена "внутрішня" посилання, яка приймає значеннявнутрішнього адреси (зміщення) елемента щодо вибраної структури.
    Формування та використання такого посилання ясноз прикладу:

    struct dat

    (int day, month, year; void Getdat (); void Putdat (); void Nextdat ();

    )

    int dat:: * p;// Посилання на елемент типу int

    // в структурі datp = & dat:: month;// Значення p - зміщення (адреса)

    // елементу month у структурі типу

    // dat

    dat x , * px = &x;//

    x. * p = 5;// Звернення по внутрішній посиланнямpx-> * p = 5;//. *

    // -> *
    Еквівалентноx.month = 5;px-> month = 5;

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

    void (dat:: * fun) ();// Посилання на елемент-функцію

    // структури dat

    fun = & dat:: Putdat ();// Значення fun - посилання?? а

    // елемент-функцію Putdat в dat
    (x. * fun) ();// Виклик елемента-функції по
    (px-> * fun) ();// посиланням fun для структури x

    // і для структури за посиланням px
    Еквівалентноx.Putdat ();px-> Putdat ();

    2.10 Незмінні змінні (константи)

    ----------------------- ----------------

    У Сі + + введений додатковий контроль за зміною значеньзмінних. Ключове слово const, що використовується при визначенні таініціалізації змінної, забороняє її зміну, що контролюєтьсятранслятором при її подальше використання. Така ж можливістьіснує і для формальних параметрів функції, наприклад:

    const int n = 5; n + +;// Заборонено

    int xxx (const int m)

    (m + + ;// Заборонено

    )

    Стосовно до посиланням const може використовуватися у двох варіантах,стосовно до самої посиланням (адресу) і стосовно до указуемомузначенням:

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

    const char * p; p = "1234567890";// Дозволено присвоювання посиланням p + = 3;// Дозволено модифікація посилання

    * ( p 3) = '3 ';// Заборонено присвоювання за посиланням

    (* p) + +;// Заборонено інкремент за посиланням

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

    char const * p = "1234567890"; char c;

    (* p) = '3 ';// Дозволено присвоювання за посиланням

    p + +;// Заборонено зміна значення c = * (p 3);// самої посилання

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

    const char const * p = "1234567890";

    2.11 Загальні зауваження про доповнення в Сі + +

    ----------------- -----------------------

    Основні відмінності Сі + + від "класичного" Сі:

    - структура (struct) наближена за властивостями до базових типамиданих (char, int);

    - введено поняття елементу-функції. Елементи-функції відіграютьроль своєрідного "інтерфейсу" для використання певноїпрограмістом структури;

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

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

    Лекція 3. Класи. Об'єкти. Конструктори і деструктори

    ---------------------------------------- ------------

    3.1.Понятіе класу і об'єкту в Сі + +

    -------------- --------------------

    У самому простому вигляді клас визначається в Сі + + як структура, робота з елементами якої можлива лише через елементи-функції . На відмінувід структури клас має "приватну" (особисту) частина, елементи якої неможуть бути доступні інакше як через інші елементифункціі, і "публічну"
    (загальну) частина, елементиякої можуть бути використані безпосередньо. Об'єктом називаєтьсяобумовлена в програмі змінна, тип якої визначенояк клас (структура):

    Визначення структури Визначення класу
    ------------------------- ------------------------- ---------- struct dat class dat
    ((//Приватна частинаint day, month, year; int day, month, year; public:// Публічна частинаvoid SetDat (int, int, int); void SetDat (int, int, int);void SetDat (char *); void SetDat (char *);
    ) Аа)void main () void main ()
    ((
    //Визна-ня змінних a, b// визна-ня об'єктів a, b класу datdat a, b; dat a, b;a.day = 5;// Безпосереднє використанняa.month = 12;// приватною частини об'єкта забороненоbAA.SetDat ( "12,12,1990"); b.Setdat ( "12,12,1990");
    ))

    "Приватна" частина класу не обов'язково повинна слідувати на початкувизначення класу. Для її позначення в довільному місцівизначення класу можна використовувати службове слово private.

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

    - статичні (зовнішні), що створюються в статичної пам'яті програми та існуючі протягом всього часу роботи програми;

    - автоматичні, що створюються в стеку в момент виклику функції ізнищувані при її завершенні;

    - динамічні, що створюються і знищувані у вільній пам'яті завдання вмоменти виконання функцій malloc () і free () або виконання операторів new іdelete.

    Відповідно в програмі можливе визначення статичних,автоматичних та динамічних об'єктів одного класу:

    class dat

    (....... )dat a, b;// Статичні об'єктиdat * p;// Посилання на об'єктvoid main ()
    (dat c, d;// Автоматичні об'єктиp = new dat;// Динамічний об'єкт
    ...delete p;// Знищення динамічного об'єкта
    )% 2d-% 2d-% 4dn ", day, month, year);
    )
    //------------------------------------------------ ------ dat a ( "12-12 -
    1990 ");// Зовнішня мінлива - конструктор

    // викликається перед main ()dat b [10];// Масив об'єктів - конструктор без

    // параметрів викликається перед main ()void xxx (dat & p)
    (dat c (12,12);// Викликається Конструктор dat (int, int, int)

    // для автоматичного об'єктаdat d = p;// Конструктор для автоматичного об'єкта не
    ...// Викликається, тому що об'єкт ініціалізується
    ...// Копіюванням
    )// При виході з функції викликаються деструктори

    // для об'єктів c і dvoid main ()
    (int i, n;scanf ( "% d", & n);dat * p = new dat [n];// Створення масиву динамічних об'єктів

    // конструктор без параметрів явно викликаєтьсяfor (i = 0; inext = this; lst = this;)
    )
    //------------------------------------------------ ------- voidlist:: extract ()
    (list * p, * pred;// Пошук поточного та попередньогоfor (pred = NULL, p = fst; p! = NULL;// в списку pred = p, p = p-> next) if (p = this) break;// Якщо знайдено - вихідif (p! = NULL)

    (//Знайдено - виключення зі списку if (pred == NULL) fst = next; else pred-> next = next;

    ) < br>)
    //------------------------------------------------ ------- voidlist:: show ()
    (list * p;for (p = fst; p! = NULL; p = p-> next)

    (... висновок інформації про об'єкт ... )
    )
    //------ При створенні об'єкта він поміщається в список -----------list:: list ()
    (insfst ();
    )
    //------ При знищенні об'єкта він виключається зі списку ------list:: ~ list ()
    (extract ();
    )

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

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

    class list

    (...static void show ();// Стaтіческая функція перегляду

    )// всього списку об'єктів
    //------------------------------------------------ ------- static voidlist:: show ()
    (list * p;for (p = fst; p! = NULL; p = p-> next)

    (... висновок інформації про об'єкт ... )
    )
    //------------------------------------------------ ------- void main ()
    (...list:: show ();// Виклик функції по повному імені
    )

    Лекція 4. Перевизначення операторів.

    ------------------------------------

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

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

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

    Для перевизначення операції використовується особлива форма елемента -функції з заголовком такого вигляду:

    operator ()

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

    Список формальних параметрів функції є списком операндів
    (кількість, типи, способи передачі) операції.

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

    Є два способи опису функції, що відповідаєперевизначають операції:

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

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

    В якості прикладу розглянемо довизначення стандартних операцій наддатами.

    # include
    # include
    # include

    static int days [] = (0,31,28,31,30,31,30,31,31,30,31,30,31);

    class dat

    (int day, month, year;public: void next ();// Element-функція обчислення

    // наступного для dat operator ++();// Операція + + dat operator + (int);// Операція "дата + ціле"

    // с неявним операндом через thisfriend dat operator + (dat, int)// Операції з явною передачеюfriend dat operator + (int, dat)// всіх параметрів за значенням dat ();// Конструктори dat (int, int, int);// (див. попередні приклади) dat (char *);//

    ~ dat ();// Деструктор

    );// (див. попередні приклади)


    //------ Функція обчислення наступного дня --------------------//< br>Використовується посилання на поточний об'єкт this,
    //Який ізменяетсмя в процесі операції
    //------------------------------------------------ ------- void dat:: next ()
    (day + +;if (day> days [month])

    (if ((month == 2) & & (day == 29) & & (year% 4 == 0)) return; day = 1; month + +; if (month == 13)

    (month = 1; year ++;

    )

    )
    )
    //------ Операція інкремента дати -----------------------------// 1. Формаелемента-фукнціі з неявним операндом за посиланням this
    //2. Повертає копію вхідного об'єкта (операнда) до збільшення
    //3. Відповідає операції dat + + (збільшення після використання)
    //4. Зауваження: для унарний операцій типу - або + + використання
    //Їх до або після операнда не має значення (викликається один
    //І та ж функція).
    //------------------------------------------------ -------dat dat:: operator ++()< br>(

    // Створюється тимчасовий об'єктdat x = * this;// У нього копіюється значення поточного об'єктаdat:: next ();// Збільшується значення поточного об'єктаreturn (x);// Повертається тимчасовий об'єкт
    )

    //------ Операція "дата + ціле" ---------------------------- -// 1. Element -функція з неявним перший аргументом за посиланням this
    //2. Вхідний об'єкт не змінюється, результат повертається копією
    //Внутрішнього автоматичного об'єкта x
    //------------------------------------------------ ------- datdat:: operator + (int n)
    (dat x;x = * this;// Копіювання поточного об'єкта в xwhile (n -! = 0) x.next ();// Виклик функції next для об'єкту xreturn (x);// Повернення копії об'єкта x
    )

    //------ Операція "дата + ціле" ---------------------------- -// 1.
    Дружня елемент-функція з повним списком аргументів
    //2. Альтернативний варіант попередньої функції
    //3. Перший операнд класу dat - передається за значенням,
    //Тому може модифікуватися без зміни початкового об'єкта
    //------------------------------------------------ ------- datoperator + (dat p, int n)
    (while (n -! = 0) p.next (p);// Виклик функції next для об'єкта preturn (p);// Повернення копії об'єкта x
    )

    //------ Операція "ціле + дата" ---------------------------- -// 1.
    Дружня елемент-функція з повним списком аргументів
    //2. Другий операнд класу dat - передається за значенням,
    //тому може модифікуватися без зміни початкового об'єкта
    //------------------------------------------------ ------- datoperator + (int n, dat p)
    (while (n -! = 0) p.next ();// Виклик функції next для об'єкта preturn (p);// Повернення копії об'єкта p
    )

    //---------------------------------------- ---------------void main ()
    (int i;dat a;dat b (17,12,1990);dat c (12,7);dat d (3);dat e;dat * p = new dat [10];clrscr ();e = a + +;d = b 15;for (i = 0; i 0; month + +)// Віднімання днів по місяцях

    (p -= days [month]; if (month == 2 & & year% 4 == 0) p -- ;

    )month -;// Відновлення останньогоp + = days [month];// місяцяif (month == 2 & & year% 4 == 0) p + +;day = p + 1;
    )

    void main ()
    (dat a ( "12-05-1990");// дата, визначена текстовим рядкомdat b;// Поточна датаint c;long d;

    // Явне перетворення до longprintf ( "З 12-05-1990 пройшло% 4ld днейn", (long) b-(long) a);

    // Явне перетворення до intprintf ( "У цьому році пройшло% 3d днейn", (int) b);c = b;// Неявно перетворення при присвоєнніd = b - a;// Операція dat-dat

    printf ( "З 12-05-1990 пройшло% 4ld днейn", d);printf ( "У цьому році пройшло% 3d днейn", c);
    )

    5.3 Перевизначення операцій new та delete

    ----------------------------- -----------

    Операції створення та знищення об'єктів у динамічній пам'яті можутьбути перевизначені наступним чином:

    void * operator new (size_t size); void operator delete (void *);

    де void * - посилання на область пам'яті, що виділяється під об'єкт, size - розмір об'єкта в байтах.

    Перевизначення цих операцій дозволяє написати власнерозподіл пам'яті для об'єктів класу.

    5.4 Перевизначення операцій [], (), ->

    ------------------- -------------------< br>Перевизначення ():
    ------------------- class one

    (public: typeout operator () (type1, type2);

    );

    Виклик: type1 a;// Виклик оператора збігається з type2 b;// синтаксисом виклику функції one obj;// з ім'ям даного об'єкта

    ... obj (a, b) ... еквівалентно obj.operator () (a, b)

    Перевизначення ->:
    ------------------ class two

    (public: type Y;

    );

    class one

    (two operator-> ();// Операція повинна повертати об'єктабо two * operator-> ();// або посилання на об'єкт класу two,

    );// в якому визначений елемент Y

    Виклик: one obj;

    ... obj-> Y .. еквівалентно (obj.operator-> ()) -> Y

    Перевизначення []: використовується для моделювання віртуальних
    -------------------- Масивів елементів певного типу.class text_page

    (char ** page;// Масив посилань на рядкиpublic:int operator [] (char *);// Асоціативний пошук індексу

    // по рядкуchar * operator [] (int);// Виділення рядка за індексом

    );

    5.5 Перевизначення операції копіювання об'єктів

    ------- -----------------------------------------

    Kaк відомо , визначення об'єкта класу у вигляді

    =

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

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

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

    class string

    (char * s;// Посилання на рядок int sz;// Фразаpublic: string (string &);// Конструктор копіювання

    );// створює копію рядки у динамічній

    // пам'яті для об'єкта - приймачаstring:: string (string & right)

    (s = new char [right-> sz]; strcpy (s, right-> s);

    ) < p> Лекція 6. Похідні класи

    ---------------------------

    6.1 Вкладені класи

    -------------------

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

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

    class man

    (char name [20];// Інші елементи класу char * address; dat dat1;// Дата народження dat dat2;// Дата вступу на роботуpublic: void newadr ();// Element-функція man (char *);// Конструктор

    )

    //----- Функція "Змінити адресу проживання" ---------------- voidman:: newadr ()

    (int n; char s [80];// Рядок нової адреси if (address! = NULL) delete address;// Звільнити пам'ять printf ( "Введіть нову адресу:" ); gets (s); address = new char [strlen (s) +1];// Зайняти нову пам'ять strcpy (address, s);// Заповнити поле адреси

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

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

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

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

    class man

    (char name [20];// Інші елементи класу dat dat1;// Дата народження dat dat2;// Дата надходження на роботуpublic: man (char *, char *, char *);// Конструктори man (char *);

    )
    //----- Конструктор класу man з неявним викликом конструкторів
    //Для dat1 і dat2 без параметрів
    //------------------------------------------------ -----man:: man (char * p)

    (

    )
    //----- Конструктор класу man з явним викликом конструкторів
    //Для dat1 і dat2 з параметрами
    //------------------------------------------------ --------- man:: man (char
    * p, char * p1, char * p2): dat1 (p1), dat2 (p2)

    (| | |

    // --- Тіло конструктора --- | | |

    ) | | |

    Виклик конструктора для ------------------ | | вкладеного об'єкта dat1 | |

    Як параметр передається ------------- | рядок - другий параметр виклику | конструктора для класу man Виклик конструктора для вкладеного об'єкта dat2

    void main -- ---- Рядок конструктора man
    (|man JOHN ( "John", "8-9-1958", "15-1-1987");
    ) | L ------ Рядок передається

    Рядок передається конструктору об'єкта конструктору об'єкта dat2 в об'єкті man dat1 в об'єкті man

    6.2 Похідні класи

    -- --------------------

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

    Старий клас при цьому називається базовим класом

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status