68937

Перевантаження операторів „«“ і „»“

Лекция

Информатика, кибернетика и программирование

Оператор виведення називається оператором вставки insertion opertor тому що він вставляє символи в потік. Функції що перенавантажують оператори вставки і витягання називаються функціями вставки inserters і витягання extrctors відповідно. Створення власних функцій вставки...

Украинкский

2014-09-27

45 KB

0 чел.

Лекція № 29

Тема: Перевантаження операторів "«"і "»"

План

  1.  Створення власних функцій вставки
  2.  Створення власних функцій витягнення

Як відомо, оператори "«" і "»" в мові С+ + перевантажені і дозволяють вводити і виводити дані вбудованих типів. Крім того, оператори "«" і "»" можна перенавантажувати так, щоб вони виводили об'єкти класів, визначених користувачем.

Оператор виведення "«" називається оператором вставки (insertion operator), тому що він вставляє символи в потік. Аналогічно оператор введення "»" називається оператором витягання (extraction operator), тому що він витягує символи з потоку. Функції, що перенавантажують оператори вставки і витягання, називаються функціями вставки (inserters) і витягання (extractors) відповідно.

Створення власних функцій вставки

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

ostream &operator»  (ostream &stream,  клас obj)

{

// Тіло функції вставки

}

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

Усередині функції вставки можна виконувати будь-які операції. Власне, саме вони визначають суть функції. Проте функцію вставки не слід дуже ускладнювати. Наприклад, абсолютно недоцільно примушувати функцію вставки попутно обчислювати число "пі" з точністю до ЗО десяткових цифр!

Продемонструємо функцію вставки на прикладі об'єктів класу phonebook.

class phonebook {

public:

char name[80];

int areacode;

int prefix;

int num;

phonebook(char *n,   int a,   int p,   int nm)

{

strcpy(name,  n); areacode = a; prefix = p; num = nm;

}

};

У цьому класі зберігаються імена і номери телефонів. Подивимося, як виглядає функція вставки для цього класу.

// Вивести на екран ім'я і номер телефону,

ostream &operator»(ostream Sstream,  phonebook о)

{

stream « о.name « "  ";

stream « "(" « o.areacode « ")   ";

stream « o.prefix « "-" « о.num « "\n";

return stream;

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

}

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

int main ()   

{

phonebook а("Тед",   111,   555,   1234);

phonebook Ь("Аліса",  312,  555,  5768);

phonebook с("Том",  212,   555,   9991);

cout « а « b « с;

return 0;

}

Результати роботи цієї програми такі.

Тед  (111)   555-1234

Аліса   (312)   555-5768

Том  (212)   555-9991

Зверніть увагу на те, що функція вставки не є членом класу phonebook. На перший погляд, це здається дивним, проте причину легко зрозуміти. Якщо операторна функція є членом класу, її лівим операндом (неявно передаваним за допомогою покажчика this) є зухвалий об'єкт. Крім того, цей операнд є об'єктом класу, членом якого є сама операторна функція. Змінити цю ситуацію неможливо. Отже, якщо перевантажена операторна функція є членом класу, її лівий операнд є потоком, а правий — об'єктом даного класу. Отже, перевантажені функції вставки не можуть бути членами класу, для якого вони перевантажуються. Змінні name, areacode, prefix і num в попередній програмі є відкритими, тому функція вставки має до них доступ.

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

class phonebook  {

friend ostream &operator»(ostream &streara,  phonebook o);

};

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

stream « о.name « "  " ;

cout « о.name « " " ;

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

Створення власних функцій витягання

Функції витягання є антиподами функцій вставки. Вони мають наступний вигляд.

istream &operator»  (istream Sstream,  клас &obj)

{

// Тіло функції витягання

return stream;

}

Функція витягання повертає посилання на потік типу istream, тобто на потік введення. її першим параметром повинне бути посилання на потік типу istream. Зверніть увагу на те, що другим параметром повинне бути посилання на об'єкт класу, для якого перевантажена функція витягання. Це дозволяє модифікувати об'єкт при виконанні операції введення (витягання).

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

istream &operator»(istream &stream,  phonebook &o)

{

cout « "Введіть ім'я:   ";

stream « о.name;

cout « "Введіть код міста:   ";

stream « о.areacode;

cout « "Введіть префікс:   ";

stream « о.prefix;

cout « "Введіть номер:   ";

stream « о.num;

cout « "\n";

return stream;

}

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

Розглянемо приклад використання функції витягання для класу phonebook.

int main()

{

phonebook a;

сіn » a;

cout « a;

return 0;

}

Фактично функція витягання для класу phonebook не дуже ефективна, оскільки оператори cout необхідні, тільки якщо потік введення пов'язаний з інтерактивним пристроєм, наприклад консоллю (тобто коли потоком введення є потік сіп). Наприклад, якщо функція витягання застосовується до потоку, пов'язаного з файлом, оператори cout стають непридатними. Забави ради можете спробувати відмінити виконання операторів cout, якщо потоком введення не є потік сіп. Наприклад, можна додати в програму операторів вигляду

if(stream == сіп)   cout « "Введіть ім'я:   ";

Тепер запрошення до введення з'явиться тільки в тому випадку, якщо пристроєм виводу є екран.


 

А также другие работы, которые могут Вас заинтересовать

13116. Бастауыш сынып оқушыларының зерттеу-ізденушілік жұмыстарын ұйымдастыру 366.5 KB
  Бастауыш сынып оқушыларының зерттеуізденушілік жұмыстарын ұйымдастыру әдістемелік нұсқау Бұл кітапшада Өскемен қаласының № 44 мектеплицейінің бастауыш сыныптарында сыныптан тыс жүргізілетін Зерде ғылыми қоғамының этномәдениет секциясын ұйымдастырылу ү
13117. Батыс Еуропадағы орта ғасырдағы тәрбие және мектеп 43 KB
  Батыс Еуропадағы орта ғасырдағы тәрбие және мектеп. Мазмұны: 1. Орта ғасырдағы діни мектептердің пайда болуы. 2. Қайта өрлеу дәуіріндегі педагогика және мектеп. 1. Орта ғасырдағы діни мектептердің пайда болуы. Құлдық қоғамның ыдырауы және құлауы оны жаңа фео...
13118. Бұқар жырау мен Дулат Бабатайұлының тәлім тәрбиелік идеялары 47.5 KB
  Бұқар жырау мен Дулат Бабатайұлының тәлім тәрбиелік идеялары 1. Бұқар жыраудың тәлімтәрбиелік идеялары. 1668-1781 ХҮІІІ ғасырда Қазақстанда ағартушылық ойпікірдің дамуында өзіндік із қалдырған ақынжыраулар поэзиясының көрнекті өкілі Бұқаржырау Қалқаманұлы....
13119. Сухомлинскийдің В.А. педагогикалық идеясы 38.5 KB
  В.А.Сухомлинскийдің педагогикалық идеясы 1918-1970 В.А.Сухомлинскийдің шығармашылығы әрбір жыл өткен сайын біздің елімізде сол сияқты шетелде ғылыми және педагогикалық жұртшылықтың тарапынан бірденбір ерекше көңіл бөлініп келеді. Бұл кездейсоқтық емес. Оның талда...
13120. Белинский В.Г. мен А.И.Герценнің педагогикалық теориясы 44.5 KB
  В.Г.Белинский мен А.И.Герценнің педагогикалық теориясы. В.Г.Белинскийдің педагогикалық көзқарастары. 18111848 ХІХ ғасырдың 3040 жылдары орыстың прогрессивтік қоғамдықпедагогикалық ойпікірінің дамуына В.Г.Белинский мен А.Н.Герцен ерекше роль атқарды. Революциял
13121. Ғұмар Қараштың педагогикалық көзқарастары 43.5 KB
  Ғұмар Қараштың педагогикалық көзқарастары. 18751921 жж. Қазан төңкерісіне дейінгі Қазақстанда қоғамдықсаяси ағартушылықпедагогикалық ойпікірдің дамуына өзінің өлшеусіз үлесін қосқан ХХ ғ.бас кезіндегі қазақ әдебиетінің ең көрнекті қайраткерлерінің бірі ағартуш...
13122. Дамыта оқытудың тиімділігі 49.5 KB
  Дамыта оқытудың тиімділігі Оқу адамның психикалық дамуының формасы элементі. Кез келген оқыту белгілі бір мөлшерде адамды дамытады. Даму ұғымы сөздікте ... мөлшерлік өзгерістердің белгілі бір өлшем шегінен шығып сапалық өзгерістерге айналуыдеп түсі...
13123. Джон Локктың педагогикалық теориясы 42.5 KB
  Джон Локктың педагогикалық теориясы. 16321704 Саясиәлеуметтік және философиялық дүниетанымы. 1688 жылы Англияда буржуазиялық төңкеріс болды. Ол өндірістік төңкеріске негіз дайындады. Бұл төңкеріс жаңа кезеңнің буржуазияның үстемдік ету кезіңін жария етті ол ...
13124. ӘЛКЕЙ МАРҒҰЛАННЫҢ ПЕДАГОГИКАЛЫҚ ҚЫЗМЕТТЕРІ 40.5 KB
  ӘЛКЕЙ МАРҒҰЛАННЫҢ ПЕДАГОГИКАЛЫҚ ҚЫЗМЕТТЕРІ С. Сұрағанов Л.Н.Гумилев атындағы Еуразиялық ұлттық университеті Астана қ. Ғұлама ғалым Әлкей Хақанұлы Марғұланның тікелей оқытушылық қызметпен айналысқанын көрсететін бірнеше нақты мәліметтер бар. Әлкей 1915 жылы Ба...