67370

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

Лекция

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

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

Украинкский

2014-09-07

85.5 KB

9 чел.

Лекція № 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++ і було винайдено нову об'єктно-орієнтовану систему введення-виведення. Як уже зазначалося вище, С++-підхід до введення-виведення даних дає змогу перевизначати оператори "<<" і ">>" так, що вони можуть працювати з класами, які створюють програмісти.


 

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

13785. Человек и общество (Обществознание, часть 2, 11 класс) 1.69 MB
  Л.Н.Боголюбов А.Ю.Лазебникова Л.Ф.Иванова. Человек и общество Обществознание часть 2 11 класс Раздел I. Глава I. Цивилизация. ЦИВИЛИЗАЦИЯ И КУЛЬТУРА Развитие культуры и цивилизации неразрывно связано: вне духовных ценностей созданных в процессе ку
13786. ВВЕДЕНИЕ В КУЛЬТУРОЛОГИЮ. ОСНОВНЫЕ ПОНЯТИЯ КУЛЬТУРОЛОГИИ В СИСТЕМАТИЧЕСКОМ ИЗЛОЖЕНИИ 1.08 MB
  А. Б. ЕСИН ВВЕДЕНИЕ В КУЛЬТУРОЛОГИЮ ОСНОВНЫЕ ПОНЯТИЯ КУЛЬТУРОЛОГИИ В СИСТЕМАТИЧЕСКОМ ИЗЛОЖЕНИИ Есин А. Б. Е 83 Введение в культурологию: Основные понятия культурологии в систематическом и...
13787. МЕЖДУНАРОДНОЕ ПРАВО В УСЛОВИЯХ ВОЕННЫХ КОНФЛИКТОВ 205.5 KB
  МЕЖДУНАРОДНОЕ ПРАВО В УСЛОВИЯХ ВОЕННЫХ КОНФЛИКТОВ [1] 1. Понятие основных принципов международного права. Источники международного права. Понятие и виды субъектов международного права. [2] 2. Понятие и основные принципы коллективной безоп
13788. Клименко А. В. Обществознание 1.76 MB
  Данное пособие предназначено в помощь учащимся старших классов школ и абитуриентам вузов, готовящимся к сдаче экзамена за курс «Обществознание». Оно избавит читателей от длительной и трудоемкой работы по изучению огромного количества литературы.
13789. Основы права Под редакцией профессора В. В. Лазарева 1.42 MB
  Настоящее учебно-методическое пособие предназначено для преподавателей курса «Основы права» в средних учебных заведениях. Оно подготовлено тем же коллективом авторов, что и учебник «Основы права» под редакцией академика РАЕН В.В. Лазарева, адресованный учащимся
13790. А.И. СОЛОВЬЕВ ПОЛИТОЛОГИЯ, ПОЛИТИЧЕСКАЯ ТЕОРИЯ, ПОЛИТИЧЕСКИЕ ТЕХНОЛОГИИ 3.41 MB
  А.И. СОЛОВЬЕВ политология ПОЛИТИЧЕСКАЯ ТЕОРИЯ ПОЛИТИЧЕСКИЕ ТЕХНОЛОГИИ В данном издании освещаются важнейшие проблемы политической науки традиционно включаемые в фундаментальные курсы зарубежных и отечественных университетов. Наряду с этим в книге раскрывают...
13791. Экономика Общий курс 3.32 MB
  Экономика Общий курс Учебник Фундаментальной теории экономики по дисциплинам: экономика введение основы общая теория рыночная экономика экономическая теория теоретическая экономика политэкономия микроэкономика макроэкономика Войтов А. Г. Э...
13792. Обществознание на «отлично»: основные понятия, персоналии, образцы эссе 673 KB
  Обществознание на отлично: основные понятия персоналии образцы эссе Справочнометодическое пособие для выпускников школ и преподавателей Волкова Т.И. Заслуженный учитель республики Хакасии Почетный работник общего образования РФ Предлагаемое уч...
13793. Обществознание в таблицах 1.09 MB
  Тема 1 Обществознание. Обществознание – это сводный учебный курс содержащий основные выводы современных наук об обществе о законах его развития о человеке. Система наук об обществе: Социальная философия Частные социальн...