Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Kurs_lektsiy samost.doc
Скачиваний:
3
Добавлен:
02.12.2018
Размер:
81.41 Кб
Скачать

10 Перевантаження операторiв.

10.1 Перевантаження операторів. Загальний підхід.

В С++ допускається перевантаження не лише функцій, як було показано вище, але і операторів. Така можливість надається при роботі з класами. Надалі не будемо акцентувати увагу на термінах оператор-операція, вважаючи їх тотожніми. Для перевантаження операторів використовується ключове слово operator. Щоб перевантажити оператор необхiдно описати функцiю такого виду:

<mun> operator <знак операцiї> (параметри).

Перевантажувати можна всi операцiї, крім “*”, “::”,” sizeof” та “.” .

По вiдношенню до класiв iснують два основних способи визначення перевантажених операторiв:

1. перевантаженi оператори оголошуються як функцiї дружнi до класу;

2. перевантаженi оператори є членами класу:

Приклад:

class complex{

double re, im;

public: complex (double r, double i)

{re=r, im=i;}

friend complex operator +(complex, complex);}

void ()

{complex a=complex (1,3.1);

complex b=complex (1.2,2);

complex c=b;

a=b+c; //(1)

c=a+complex (1,2);} //(2)

complex operator+(complex a,complex b);

{complex c;

c.re=a.re+b.re;

c.im=a.im+b.im;

return c;}

Замiсть (1)-(2) можемо записати:

а=operator + (b,c) ;

c=operator (a,complex(1,2));

Бачимо, що оголосивши перевантажений оператор + як дружню функцію до класу, можемо вільно використовувати значок “+” по відношенню до екземплярів класу. Причому в точках, де стоїть перевантажена операцiя, відбувається виклик функцiї оператора( в даному випадку оператор +). Очевидно, що компілятор буде розрізняти + перевантажений та + “звичайний”. Якщо десь буде фігурувати звичайний арифметичний вираз, то ніяких конфліктів не виникне. Іншими словами, перевантажуючи операції ми ніби розширюємо поле їх дії на відповідні екземпляри класів.

Перепишемо приклад таким чином, щоб перевантажений оператор був членом класу

class complex {

double re,im;

public:

complex (double r,double i)

{re=r; im=i;}

complex operator + (complex);

}

Бачимо, що в перевантаженому операторi + , на вiдмiну вiд попереднього прикладу, є один формальний параметр типу complex. Другий просто непотрібний. Адже в якості другого параметра виступає вказiвник на об'єкт this, для якого викликається функцiя-член.

Необхідно відмітити, що для перевантажених операторiв повинна обов’язково зберiгатись вихідна кiлькiсть операндiв:

class TStr {

private:

char val[12]

public:

TStr() {value [0]=0;}

TStr (const char *s);

long GetValue(void) {return atol(val);}

frend long operator + (TStr a, TStr b);

frend long operator - (TStr a, TStr b);

};

main()

{TStr a="1234";

TStr b="4321";

cout <<"\na+b+6="<<(a+b+6);

cout <<"\na-b+10="<<(a-b+10)<<'\n';

TStr : : TStr(const char * s)

{ strncpy (value, s, 11);

value [11]=0; }

long operator + (TStr a, TStr b)

{return (atol(a.value) + atol(b.value)); }

long operator - (TStr a,TStr b)

{return (atol(a.value) - atol(b.value));

Перепишемо цей приклад так, щоб перевантажені оператори були членами класу:

class TStr {

private:

char val [12]

public:

TStr () {value [0]=0;}

TStr (const char * s)

long GetValue (void) {return atol (val);}

long operator + (TStr b);

long operator - (TStr a);

};

main()

{TStr a="1234";

TStr b="4321";

cout <<"\na+b+6="<<(a+b+6);

cout <<"\na-b+10="<<(a-b+10)<<'\n';

retyrn 0;}

TStr : : TStr (const char * s)

{strncpy (value,s,11);

value [11]=0;}

long TStr ::operator + (TStr a, TStr b)

{return (atol(a.value) + atol(b.value));}

long TStr ::operator - (TStr a, TStr b)

{return (atol(a.value) - atol(b.value));}

Таким чином, як бачимо з наведених вище прикладiв, для будь-якої перевантаженої бiнарної операцiї @ вираз aa @ bb iнтерпретується як operator @ (aa,bb) чи aa. operator @ (bb) в залежностi вiд того, як визначена дана операцiя (функцiя-член чи функцiя друг). Звідси бачимо, що перевантажена функцiя-член не може мати перший параметр-елемент основного типу. Адже 2 @ aa iнтерпретується як 2.operator @ (aa) , що не допускається.

Аналогiчно для будь-якої унарної операцiї @ оператор aa@ чи @aa iнтерпретується як operator @(aa) чи aa. operator @ ().

Розглянамо приклад:

clas x {

friend x operator - (x);

friend x operator - (x,x)

friend x operator - ();// помилка

friend x operator - (x,x,x); // помилка

};

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]