68948

Перевантаження операторів

Лекция

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

Перевантаження скорочених операторів присвоєння Обмеження на перевантаження операторів З перевантаженням функцій тісно пов’язаний механізм перевантаження операторів. У мові C можна перенавантажувати більшість операторів набудувавши їх на конкретний клас.

Украинкский

2014-09-27

40 KB

2 чел.

Лекція № 10

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

План:

  1.  Перевантаження операторів
  2.  Створення операторної функції члена
  3.  Створення префіксної і постфіксної форм операторів інкрементації і декрементації.
  4.  Перевантаження скорочених операторів присвоєння
  5.  Обмеження на перевантаження операторів

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

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

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

Створення операторної функції-члена

Операторна функція-член має наступний вигляд:

тип_возвращаемого_значения имя_класса::operator# (список-аргументів)

{

...   //  Операції

}

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

Розглянемо простій приклад. Ця програма створює клас 1ос, в якому зберігаються географічні координати: широта і довгота. У ній перевантажується оператор "+". Уважно вивчите цю програму, приділяючи особливу увагу визначенню функції operator* ().

#include <iostream>

using namespace std;

class loc {

int longitude, latitude;

public:

loc() {}

loc(int lg, int It) { longitude = lg; latitude = It; }

void show() {

cout « longitude « " ";

cout « latitude « "\n";

}

loc operator+(loc op2);

};

// Overload + for loc.

loc loc::operator+(loc op2)

{

loc temp;

temp.longitude = op2.longitude + longitude; temp.latitude = op2.latitude + latitude;

return temp;

}

int main() {

loc ob1(10, 20), ob2( 5, 30);

obl.show(); // Виводить на екран числа 10 20 ob2.show(); // Виводить на екран числа 5 30

оb1 = оb1 + оb2;

obl.show(); // Виводить на екран числа 15 50

return 0;

}

Як видимий, функція operator* Про має тільки один параметр, не дивлячись на те, що вона перенавантажує бінарного оператора. (Як відомо, бінарних операторів мають два операнди.) Причина полягає в тому, що операнд, що стоїть в лівій частині оператора, передається операторній функції неявно за допомогою покажчика this. Операнд, що стоїть в правій частині оператора, передається операторній функції через параметр ор2. Звідси слідує важливий висновок: при перевантаженні бінарного оператора виклик операторної функції генерується об'єктом, що стоїть в лівій частині оператора.

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

ob1  =  оb1  +  оb2;

Для того, щоб привласнити суму об'єктів оB і оb2 об'єкту оB, необхідно, щоб результат операції + мав тип loc.

Крім того, оскільки операторна функція operator* () повертає об'єкт типу loc, допускається наступний вираз:

(оb1+оb2).show() ;   //  Виводить  на  екран  суму obl+ob2

У цій ситуації операторна функція створює тимчасовий об'єкт, який знищується після повернення з функції show().

 

Створення префіксної і постфіксної форм операторів

інкрементації і декрементації

У попередній програмі був переобтяжений тільки оператор инкрементации в префіксній формі. Проте стандарт мови C++ дозволяє явно створювати окремі версії префіксного і постфіксного операторів инкрементации і декрементации. Для цього слід визначити дві версії функції operator++ () (і функції operator— () відповідно). Одна з цих версій була визначена в попередній програмі, а іншу ми визначимо нижче.

loc operator++(int x);

Якщо символи ++ передують операндам, викликається операторна функція ореrаtor++ (), якщо символи ++ слідують за операндами, викликається операторна функція operator++(int x).

Працюючи із старими програмами на мові C++, що містять операторів инкрементации і декрементации, слід проявляти обережність. У цих програмах неможливо розрізнити префіксну і постфіксну форму переобтяжених операторів "++" і "—". У обох випадках слід застосовувати префіксну форму.

 

Перевантаження скорочених операторів присвоювання

Скорочених операторів привласнення (наприклад, "+=", "-=" і т.п.) також можна перенавантажувати. Розглянемо операторну функцію operator+= () для класу 1ос.

loc loc::operator+=(loc op2){

longitude = op2.longitude + longitude;

latitude = op2.latitude + latitude;

return *this;

}

Обмеження на перевантаження операторів

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

Як неодноразово указувалося, усередині операторної функції можна програмувати будь-які операції. Наприклад, ніхто не забороняє перенавантажувати оператора "+" так, щоб він десять разів записував у файл рядок "Я люблю C++". Проте ці дії сильно відрізняються від звичайного сенсу оператора "+", і ви ризикуєте зруйнувати свою програму. Якщо хто-небудь стане читати її і побачить оператор оB+ОЬ2, то, природно, він припустить, що в цьому місці складаються два об'єкти, а не виконується операція висновку у файл. Отже, для значного відхилення від звичайного призначення оператора повинні існувати вагомі причини. Одна з них — необхідність перенавантажувати операторів "«" і "»". Хоча оператори побітового зрушення не мають ніякого відношення до введення-висновку, їх зовнішній вигляд настільки добре відповідає цьому призначенню, що неможливо встояти перед спокусою перенавантажувати їх новим сенсом. Та все ж, як правило, краще залишатися в рамках традиційного сенсу. За винятком оператора "-", операторні функції успадковуються похідними класами. Проте в похідному класі кожний з цих операторів знову можна перенавантажувати.


 

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

85665. Расчет машинного времени на подъем НКТ при разных скоростях подъема 695.86 KB
  Сузунское нефтегазовое месторождение расположено на севере Красноярского края Российской Федерации. Вместе с Лодочным, Тагульским и Ванкорским месторождениями входит в Ванкорский блок и относится к Большехетскому нефтегазоносному району Западно-Сибирской нефтегазоносной провинции.
85670. Исследования проблемы дифференциации товаров 184.5 KB
  Целью данной работы является исследования проблемы дифференциации товаров. С экономической точки зрения она предполагает всесторонний подход и состоит в системном взгляде на данное явление. Данный подход предполагает выявление взаимосвязей в рамках экономической системы
85671. Тепловой расчет котельного агрегата Е-400-13, 8-560 КДТ (ТПЕ-429) 247.23 KB
  Задание на курсовое проектирование должно содержать следующие данные: а тип парогенератора; б месторождение и марку топлива его зольность влажность и способ сжигания; в производительность парогенератора давление и температуру перегретого пара на выходе из пароперегревателя; г температуру питательной воды...