89793

Перегрузка операций в классах

Лекция

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

Поскольку в С++ операции, рассматриваются как функции, то их можно переопределять так, что они будут работать не только с числами, а даже с графическими объектами, строками и вообще с чем угодно.

Русский

2015-05-13

62.03 KB

2 чел.

Перегрузка операций в классах

Определение (перегрузка) операций в классах

Поскольку в С++ операции, рассматриваются как функции, то их можно переопределять так, что они будут работать не только с числами, а даже с графическими объектами, строками и вообще с чем угодно. 

C++ позволяет распространить действие любой стандартной операции на новые типы данных, вводимые пользователем. Распространить операцию на новые типы данных позволяет механизм перегрузки стандартных операций. В С++ число операций ограничено стандартным набором.

Перегружаемые операции:

  •  Арифметические и логические операторы
  •  Операторы сравнения и равенства
  •  Операторы присваивания
  •  Битовые операторы
  •  Операторы ++ и -- в постфиксном и префиксном значениях
  •  Операторы индексации массива []
  •  Вызов функции ()
  •  Оператор доступа к члену через указатель на объект -> и обращения к члену через указатель на член ->*
  •  Операторы перенаправления ввода >> и вывода <<
  •  Операторы new и delete

Для распространения действия операции на новые пользовательские типы данных программист определяет специальную функцию, называемую «операция-функция»:

тип_возвращаемого_значения operator знак_операции (спецификация _параметров_операции-функции) {операторы_тела_операции-функции}

Чтобы явная связь с классом была определена, операция-функция: 

  •  может быть компонентом класса,
  •  определена в классе как дружественная, 
  •  у нее должен быть хотя бы один параметр типа класс (или ссылка на класс).

При переопределении операции действуют следующие ограничения: 

  •   С++ не различает префиксные и постфиксные версии операций ++ и --. 
  •   операция, которую вы хотите определить, уже должна существовать в языке. Например, вы не можете определить операцию #. 
  •   нельзя переопределить следующие операции:  .     .*     ::    ?:
  •   переопределенные операции сохраняют свое первоначальное старшинство. 

При вызове операции-функции используется обычный вид бинарных операций:

C=A+B;

или полная форма вызова:

C=operator + (A,B);

Любая стандартная бинарная операция @ может быть перегружена с помощью нестатической операции-функции, входящей в число компонентов класса с одним параметром:

T operator @ (T x)

Тогда вызов операции A @ B с объектами A и B класса T в качестве операндов интерпретируется как вызов функции:

A.operator@(B)

Если @ обозначает любую унарную операцию, то выражения x@ и @x можно интерпретировать либо как x.операция@(), либо как операция@(x). Если описаны обе формы, то компилятор попытается разрешить неоднозначность путем сравнения аргументов. Аналогично, переопределение бинарной операции @ в x@y может толковаться либо x.операция@(y), либо операция@(x,y), и если определены обе формы, то компилятору требуется анализировать аргументы. 

Пример #11. Класс clock

class clock{

public:

clock (unsigned long i);//конструктор

void print() const;//вывод по формату

void tick();//добавляет 1 секунду

clock operator++(){tick(); return *this;};

clock operator –(clock c){return (tot_secs-c.tot_secs);};

friend clock operator +(clock c1, clock c2) { return (c1.tot_secs+c2.tot_secs);};

friend clock operator *(unsigned long m, clock c) {return (m*c.tot_secs);};

friend clock operator *(clock c, unsigned long m) {return (m*c);};

private:

unsigned long tot_secs, secs, mins, hours, days;

};

inline clock::clock(unsigned long i)

{tot_secs=i; secs=tot_secs% 60;

mins=(tot_secs / 60) % 60;

hours=(tot_secs / 3600) % 24;

days= tot_secs / 86400;}

void clock::tick()

{ clock temp=clock(++tot_secs);

secs=temp.secs; mins=temp.mins;

hours=temp.hours; days=temp.days;}

void clock::print() const {

cout<<days<<“ д:”<<hours<<“ ч:” <<mins<<“  м:”<<secs<<“ с:”<< endl;}

int main()

{ clock::clock t1(59), t2(172799);

cout<<“начальное время”<<endl;

t1.print(); t2.print();

++t1; ++t2;

cout<<“время через секунду”<<endl;

t1.print(); t2.print();

return 0;

}

Пример #12. Массив

#include <iostream.h>

#include <assert.h>

class vect {

public:

explicit vect(int n=10);

//инициализация вектором vect (копирующий конструктор)

vect(const vect& v);

//инициализация массивом

vect(const int a[], int n);

~vect() {delete []p;}

int ub() const {return (size-1);}

int&  operator[] (int i);

vect& operator= (const vect& v);

vect operator+ (const vect& v);

private:

int* p; int size;

}

vect::vect(int n):size(n)

{ assert (n>0);

p=new int[size];

assert (p!=0);

}

vect::vect(const int a[], int n): size(n)

{   assert (n>0);

p=new int[size];

assert (p!=0);

for (int i=0; i<size; i++) p[i]=a[i];

}

vect::vect(const vect& v):size(v.size)

{ p=new int[size];

assert (p!=0);

for (int i=0; i<size; i++) p[i]=v.p[i];

}

int& vect::operator [] (int i)

//точно также можно определить оператор 

//индексирования (): int& vect::operator () (int i)

{ assert (i>=0 && i<size);

return p[i];

}

vect& vect::operator= (const vect& v)

{ if (this != &v)

{assert(v.size==size);

for (int i=0; i<size; ++i) p[i]=v.p[i];} return *this;}

vect vect::operator+ (const vect& v)

{ assert (v.size==size);int s=size;

vect sum(s);   

for (int i=0; i<s; ++i) sum.p[i]=p[i]+v.p[i];

return sum;

}

int main(){

vect A(3),B(3);

int i,b[5];

vect C(b,5), D(C);

for(i=0;i<3;i++){A[i]=i;} B=A;

for(i=0;i<3;i++){cout<<A[i]<<' ';} cout<<endl;

for(i=0;i<3;i++){cout<<B[i]<<' ';} cout<<endl;

A=A+B;

for(i=0;i<3;i++){cout<<A[i]<<' ';} cout<<endl;

return 0;

}

Пример #13. Перегруженные операторы ввода-вывода

class rational{//класс рациональных чисел

public:

rational (){}

~rational (){}

friend ostream& operator<< (ostream& out, rational x);

friend istream& operator>> (istream& in, rational& x);

private:

long a,q;

};

ostream& operator<<(ostream& out, rational x)

{return (out<<x.a<<“/”<<x.q<<‘\t’);};

istream& operator>> (istream& in, rational& x)

{return (in>>x.a>>x.q);};

int  main()

{

rational a,b;

cin>>a>>b;

cout<<a<<b;

return 0;

}

Пример #14. Операторы указателей

#include <iostream.h>

class triple{

public:

triple(int a, int b, int c)

{i=a; j=b; k=c;}

void print()

{cout<<“\ni=”<<i<<“, j=”<<j<<“, k=“<<k;}

private:

int i, j, k;

};

triple unauthor(0, 0, 0);

class t_ptr{

public:

t_ptr(bool f, triple* p)

{access=f; ptr=p;}

triple* operator->();

private:

bool access;

triple* ptr;

};

triple* t_ptr::operator->()

{

if (access) return (ptr);

else {cout<<

“\n Несанкционированный доступ”;

return &unauthor;}

}

int main()

{

triple a(1,2,3), b(4,5,6);

t_ptr ta(false, &a), tb(true, &b);

ta->print();//доступ запрещен

tb->print();//доступ предоставлен

return 0;

}


 

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

55769. Суспільно – політичне життя й політична боротьба в Україні 1953 – 1964 рр. 444.5 KB
  Обладнання: підручник хрестоматія настінна карта атласи фрагменти відеофільмів Хрущов на XX з’їзді КПРС Усунення М. Основні поняття і терміни: десталінізація реабілітація відлига Програма КПРС. XX з’їзд КПРС; 1957 р. ухвалення нової Програми КПРС; 1963 р.
55770. Утворення давньоруської держави, її значення в історії українського народу 139 KB
  Але ці слабкості були настільки непомітними що неозброєним оком їх не побачиш тому що їх затьмарює відвага войовничість хоробрість простота мудрість і любов до рідної землі; по-друге вся діяльність князя була спрямована на зміцнення...
55771. You are what you eat. Ви є те, що ви їсте 466.5 KB
  Welcome to McDonald’s, dear friends! Nice to meet you here! We’re not going to eat here, but see how they prepare the meals. What are the most popular dishes at McDonald’s? How do we call the lunch box at McDonald’s?
55772. Системи лінійних рівнянь 1.77 MB
  При вивченні цієї теми учні отримують новий потужний апарат розв’язання задач який буде використовуватись і далі. Використання цієї програми дає змогу вчителю значно...
55774. Внеклассное мероприятие по французскому языку 64.5 KB
  Bonjour mesdmes et messieurs Dns un instnt on v commencer Instllezvous dns votre futeil bien gentiment Доброго дня пані та панове За мить ми розпочнемо Розташовуйтесь зручніше ujourd’hui nous nous sommes reunit pour jouer un peu et bien sûr pour svoir qui est plus intelligent prmi les onzièmes clsses. Permettezmoi de vous présenter des équipes : Дозвольте вам представити команди: L’équipe de 11 clsse ___________________ le chef est _______ Команда 11а класу Кістка вишні командир Тімченко Поліна L’équipe de 11B clsse...
55775. Пізнаємо себе 37 KB
  Слайд 1 Ми з вами будемо розмовляти про емоції почуття риси характеру навчимося керувати своїми емоціями. Слайд 2 Зверніть увагу зараз ми з вами знаходимося у дружньому колі ми всі рівні.
55776. Стиснення, архівування та розархівування даних. Програми-архіватори 48 KB
  Мета: Навчальна: сформувати вміння учнів використовувати програми-архіватори для стиснення архівації та розархівації файлів; Розвивальна: розвивати логічне мислення формувати алгоритмічний стиль думки поглибити знання учнів про впорядкування інформації в комп’ютері...
55777. ЕТНОГРАФІЧНА ПОДОРОЖ УКРАЇНОЮ 64 KB
  До розповсюджених на Україні художніх промислів відносяться вишивка виробництво художніх тканин килимарство різьбярство взагалі художня обробка дерева гончарство гутне скло художнє ковальство обробка металів і ювелірних виробів розпис тканин...