67370

Перевантаження операторів введення-виведення даних

Лекция

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

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

Украинкский

2014-09-07

85.5 KB

14 чел.

Лекція № 27

Тема: Перевантаження операторів введення-виведення даних

План

  1.  Особливості механізмів перевантаження операторів введення-виведення даних
  2.  Створення перевантажених операторів виведення даних
  3.  Використання функцій-"друзів" класу для перевантаження операторів виведення даних
  4.  Створення перевантажених операторів введення даних
  5.  Порівняння С- і С++-систем введення-виведення

  1.  Особливості механізмів перевантаження операторів введення-виведення даних

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

    У мові C++ оператор "<<" називається оператором виведення або вставлення, оскільки він вставляє символи у потік. Аналогічно оператор ">>" називається оператором введення або вилучення, оскільки він вилучає символи з потоку.

    Як уже зазначалося вище, оператори введення-виведення вже перевантажені (у заголовку <iostream>) для того, щоби вони могли виконувати операції потокового введення або виведення даних будь-яких вбудованих С++-типів. У цьому підрозділі можна буде дізнатися про те, як визначити ці оператори для створення власних класів.

  1.  Створення перевантажених операторів виведення даних

    Як простий приклад розглянемо механізм створення оператора виведення даних для уже відомої нам з попередніх тем такої версії класу kooClass:

class kooClass

{    public:

             int x, y, z;                         // Тривимірні координати

             kooClass(int a, int b, int c) { x = a; y = b; z = c; }

};

    Щоб створити операторну функцію виведення даних для об'єктів типу kooClass, необхідно перевантажити оператор виведення даних "<<". Один з можливих способів його реалізації має такий вигляд:

       

        // Відображення тривимірних координат x, y, z

        // Перевантажений оператор виведення даних для класу kooClass

ostream &operator<<(ostream &stream, kooClass obj)

{

stream << obj.x << ", ";

stream << obj.y << ", ";

stream << obj.z << endl;

return stream;    // Повертає посилання на параметр stream

}

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

Приклад. Демонстрація механізму реалізації перевантаженого оператора виведення даних

class kooClass

{

    public:

            int x, y, z;

            kooClass(int a, int b, int c) { x = a; y = b; z = c; }

};

    // Відображення тривимірних координат x, y, z

    // Перевизначений оператор виведення даних для класу kooClass

ostream &operator<<(ostream &stream, kooClass obj)

{

stream << obj.x << ", ";

stream << obj.y << ", ";

stream << obj.z << endl;

return stream; // Повертає посилання на параметр stream

}

void main()

{

kooClass ObjA(1, 2, 3), ObjB(3, 4, 5), ObjC(5, 6, 7);

      // Перевизначений оператор виведення даних

cout << ObjA << ObjB << ObjC;

}

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

1, 2, 3

3, 4, 5

5, 6, 7

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

ostream &operator<<(ostream &stream, class_type obj)

{

// Код операторної функції виведення даних

return stream; // Повертає посилання на параметр stream

}

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

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

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

// Версія обмеженого застосування (використанню не підлягає).

ostream &operator<<(ostream &stream, kooClass obj)

{

      cout << obj.x << ", ";

      cout << obj.y << ", ";

      cout << obj.z << endl;

      return stream;                 // Повертає посилання на параметр stream

}

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

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

  1.  Використання функцій-"друзів" класу для перевантаження операторів виведення даних

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

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

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

    Проте існує просте вирішення цього питання – оператор виведення даних можна зробити "другом" класу. Якщо функція є "другом" деякого класу, то вона отримує легальний доступ до його private-даних. Оголошення "другом" класу операторної функції виведення даних продемонструємо на прикладі класу kooClass.

Приклад. Демонстрація механізму використання функцій-"друзів" класу для   

                  перевантаження оператора виведення даних

class kooClass

{

     public:   

             int x, y, z;

             kooClass(int a, int b, int c) { x = a; y = b; z = c; }

             friend ostream &operator<<(ostream &stream, kooClass obj);

};

     // Відображення тривимірних координат x, y, z

     // Перевизначений оператор виведення даних для класу kooClass

ostream &operator<<(ostream &stream, kooClass obj)

{

stream << obj.x << ", ";

stream << obj.y << ", ";

stream << obj.z << endl;

return stream;           // Повертає посилання на параметр stream

}

void main()

{

kooClass ObjA(1, 2, 3), ObjB(3, 4, 5), ObjC(5, 6, 7);

     // Перевантажений оператор виведення даних

cout << ObjA << ObjB << ObjC;

}

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

  1.  Створення перевантажених операторів введення даних

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

   

    // Прийняття тривимірних координат x, y, z

    // Перевантажений оператор введення даних для класу kooClass

istream &operator>>(istream &stream, kooClass &obj)

{

cout << "Введіть координати x, y і z: ";

    // Перевантажений оператор введення даних

stream >> obj.x >> obj.y >> obj.z;

return stream;    // Повертає посилання на параметр stream

}

    Перевантажений оператор введення даних повинен повертати посилання на об'єкт типу istream. Окрім цього, перший параметр повинен бути посиланням на об'єкт типу istream. Цей тип належить потоку, що вказується зліва від оператора ">>". Другий параметр є посиланням на об'єкт, який приймає значення, що вводяться. Оскільки другий параметр – посилання на об'єкт, то його можна модифікувати при введенні інформації.

    Загальний формат перевизначеного оператора введення даних має такий вигляд:

istream &operator>>(istream &stream, objectType &obj)

{

     // код операторної функції введення даних

turn stream;      // Повертає посилання на параметр stream

}

    Особливості використання операторних функцій введення та виведення даних для об'єктів типу kooClass продемонстровано в такому коді програми.

Приклад. Демонстрація механізму перевантаження операторів введення/виведення

                  потокової інформації

 

class kooClass

{

int x, y, z;          // Тривимірні координати

public:

kooClass(int a, int b, int c) { x = a; y = b; z = c; }

friend ostream &operator<<(ostream &stream, kooClass obj);

friend istream &operator>>(istream &stream, kooClass &obj);

};

   // Відображення тривимірних координат x, y, z

   // Перевизначений оператор виведення даних для класу kooClass

ostream &operator<<(ostream &stream, kooClass obj)

{

stream << obj.x << ", ";

stream << obj.y << ", ";

stream << obj.z << endl;

return stream;             // Повертає посилання на параметр stream

}

  // Прийняття тривимірних координат x, y, z

  // Перевизначений оператор введення даних для класу kooClass

istream &operator>>(istream &stream, kooClass &obj)

{

cout << "Введіть координати x, y і z: ";

                      // Перевизначений оператор введення даних

stream >> obj.x >> obj.y >> obj.z;

return stream;              // Повертає посилання на параметр stream

}

void main()

{

kooClass ObjA(1, 2, 3);

cout << ObjA;             // Перевизначений оператор виведення даних

cin >> ObjA;               // Перевизначений оператор введення даних

cout << ObjA;             // Перевизначений оператор виведення даних

}

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

1, 2, 3

Введіть координати x, y і z: 5 6 7

5, 6, 7

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

  1.  Порівняння С- і С++-систем введення-виведення

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

struct myStruct     // Оголошення типу структури

{

     int count;

     char str[80];

     double balance;

}

то наявну у мові C систему введення-виведення неможливо налаштувати так, щоб вона могла виконувати операції введення-виведення даних безпосередньо над об'єктами типу myStruct. Але, оскільки центром ООП є саме об'єкти, то виникає потреба у тому, щоб у мові програмування C++ функціонувала така система введення-виведення, яку можна було б динамічно "навчати" поводженню з будь-якими об'єктами, що створюються програмістом. Саме тому для мови програмування C++ і було винайдено нову об'єктно-орієнтовану систему введення-виведення. Як уже зазначалося вище, С++-підхід до введення-виведення даних дає змогу перевизначати оператори "<<" і ">>" так, що вони можуть працювати з класами, які створюють програмісти.


 

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

55391. ПРОЕКТНА ДІЯЛЬНІСТЬ УЧНІВ НА УРОКАХ УКРАЇНСЬКОЇ МОВИ ТА ЛІТЕРАТУРИ 140 KB
  Метод проектів особливо на уроках української мови та літератури передбачає не тільки наявність субєктивно чи соціально значущої для учня проблеми не просто її дослідження пошук шляхів вирішення а й практичне впровадження отриманих результатів у тому чи іншому продукті діяльності.
55392. Проектная деятельность на уроке технологии 86 KB
  Обобщить знания о пищевом рационе режиме питания условиях приёма пищи и сформулировать правила рационального питания. Воспитывать бережное отношение к здоровью и продуктам питания.
55393. Метод проектов на уроках истории и во внеклассной деятельности 396 KB
  Материально-техническое обеспечение проекта: аудио видео стенд. Для подготовки учеников к настоящим проектам необходимо начать их знакомство с данной технологией на уровне второй ступени обучения.
55394. Використання проектної технології як засіб активізації пізнавальної діяльності учнів на уроках інформатики 339.5 KB
  Мій досвід роботи в школі показав що в розвитку зацікавленості до предмета не можна покладатися тільки на зміст виучуваного матеріалу уникаючи залучення учня до активної діяльності.
55395. Творчі проекти у початковій школі 44 KB
  Творчий проект Казка про народнопоетичні символи України Я і Україна 4 клас Мета проекту. Поглибити знання школярів про народнопоетичні символи України; розвивати творчу уяву звязне мовлення школярів; виховувати любов до Батьківщини. Учні ознайомлюються з народнопоетичними символами України; виконують завдання у групах Казкарі та Художники. Завдання Групі казкарів: скласти казки про рослинні та тваринні народнопоетичні символи України: вербу калину тополю соняшник соловейка лелеку та ін.
55396. У пошуках майбутньої професії 63 KB
  Мета: познайомити учнів з деякими професіями, стимулювати стійкий інтерес до здобуття професійних знань;розвивати ерудицію, кмітливість, винахідливість , артистизм, навики ділової гри; формувати свідоме ставлення до вибору професії.
55397. Проект по профориентации 467.5 KB
  С этого момента начинается работа над проектами. Каждый ребёнок получил задание в результате выполнения которого он должен прийти к выводу почему именно эта профессия ему нравится.
55398. МИР ПРОФЕССИЙ 241.5 KB
  Познакомить обучающихся с престижными редкими и новыми профессиями охарактеризовать предмет труда каждой профессии. Воспитывать житейское отношение к выбору профессии.
55399. Вибір майбутньої професії 145 KB
  У цьому випадку людина вивчає власні можливості інтереси здібності переглядає багато професій і свідомо обирає ту яка підходить саме для неї з урахуванням сучасних проблем суспільства та особливостей ринку праці.