на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Розробка власного класу STRING
омітимо, що функції, якими клас постачає зовнішній світ, визначаються міткою public. Відкриті функції реалізують всі можливості класу, необхідні для його клієнтів. Відкриті функції класу називають інтерфейсом класу або відкритим інтерфейсом.

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

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

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

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

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

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

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

1.6 Область дії клас і доступ до елементів класу

Дані-елементи класу (змінні, об'явлені у визначенні класу) і функції-елементи (функції, об'явлені у визначенні класу) мають областю дії клас. Функції, що не є елементами класу, мають областю дії файл.

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

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

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

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

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

Програма на мал.3 використає простий клас, названий Count, з відкритим елементом даних х типу int і відкритої функцією-елементом print, щоб проілюструвати доступ до елементів класу за допомогою операції вибору елемента. Програма створює три екземпляри змінних типу Count - counter, counterRef (посилання на об'єкт типу Count) і counterPtr (покажчик на об'єкт типу Count). Змінна counterRef об'явлена, щоб посилатися на counter, змінна counterPtr об'явлена, щоб указувати на counter. Важливо відзначити, що тут елемент даних х зроблений відкритим просто для того, щоб продемонструвати способи доступу до відкритих елементів. Як ми вже встановили, дані звичайно робляться закритими (private).

// FIG6_4. CPP

// Демонстрація операцій доступу до елементів класу. і - >

#include <iostream. h>

// Простий клас Count class Count { public:

int x;

void print () { cout << x " endl; } };

main ()

{

Count counter, // створюється об'єкт counter

*counterPtr = &counter, // покажчик на counter &counterRef = counter; // посиланя на counter

cout " "Присвоювання х значення 7 і друк по імені об'єкта: ";

counter. х =7; // присвоювання 7 елементу даних х

counter. print (); // виклик функції-елемента для друку

cout << "Присвоювання х значення 8 і друк по посиланню: ";

counterRef. x = 8; // присвоювання 8 елементу даних х

counterRef. print (); // виклик функції-елемента для друку

cout << "Присвоювання х значення 10 і друк по покажчику: "; counterPtr->x = 10; // присвоювання 10 елементу даних х counterPtr->print (); // виклик функції-елемента для друку

return 0;

}

Мал.3. Доступ до даних-елементів об'єкта й функціям-елементам за допомогою імені об'єкта, посилання й вказівника на об'єкт

Присвоювання х значення 7 і друк по імені об'єкта: 7

Присвоювання х значення 8 і друк по посиланню: 8

Присвоювання х значення 10 і друк по покажчику: 10

1.7 Конструктор класу

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

class Account {

public:

// конструктор за замовчуванням...

Account ();

// ...

private:

char *_name;

unsigned int _acct_nmbr;

double _balance;

};

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

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

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

Account (const char *name, double open_balance);

Об'єкт класу Account, ініціалізуємий конструктором, можна об'явити в такий спосіб:

Account newAcct ("Mikey Matz", 0);

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

Account (const char *name);

Інший спосіб - включити в конструктор із двома параметрами значення за замовчуванням, рівне нулю:

Account (const char *name, double open_balance = 0.0);

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

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

class Account {

public:

// конструктор за замовчуванням...

Account ();

// імена параметрів в оголошенні вказувати необов'язково

Account (const char*, double=0.0);

const char* name () { return name; }

// ...

private:

// ...

};

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

int main ()

{

// правильно: в обох випадках викликається конструктор

// с двома параметрами

Account acct ("Ethan Stern");

Account *pact = new Account ("Michael Lieberman", 5000);

if (strcmp (acct. name (), pact->name ()))

// ...

}

C++ вимагає, щоб конструктор застосовувався до певного об'єкта до його першого використання. Це означає, що як для acct, так і для об'єкта, на який указує pact, конструктор буде викликаний перед перевіркою в інструкції if.

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

От як, цілком ймовірно, буде модифіковане визначення acct усередині main ():

// псевдокод на C++,

// іллюструючий внутрішню вставку конструктора

int main ()

{

Account acct;

acct. Account:: Account ("Ethan Stern", 0.0);

// ...

}

Звичайно, якщо конструктор визначений як вбудований, то він підставляється в точці виклику.

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

// псевдокод на C++,

// іллюструючий внутрішню вставку конструктора при обробці new

int main ()

{

// ...

Account *pact;

try {

pact = _new (sizeof (Account));

pact->Acct. Account:: Account (

"Michael Liebarman", 5000.0);

}

catch (std:: bad_alloc) {

// оператор new закінчився невдачею:

// конструктор не викликається

}

// ...

}

Існує три в загальному випадку еквівалентні форми завдання аргументів конструктора:

// загалом ці конструктори еквівалентні

Account acct1 ("Anna Press");

Account acct2 = Account ("Anna Press");

Account acct3 = "Anna Press";

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

// рекомендує форма, що, виклику конструктора

Account acct1 ("Anna Press");

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

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.