89793

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

Лекция

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

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

Русский

2015-05-13

62.03 KB

3 чел.

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

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

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

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;

}


 

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

71392. Оптимизация логистических процессов и процессов продаж на «1С:Розница 8» в условиях объекта управления 2.14 MB
  Для достижения поставленной цели в рамках настоящей дипломной работы необходимо выполнить следующие задачи: Дать оценку реализации бизнес-процессов на начало момента внедрения в сети розничных магазинов Галактика.
71393. Процесс формирования издержек обращения и их учет в ОАО «Липецкоблснаб» 833.5 KB
  Роль издержек обращения для торговых организаций значительна и поиск путей их снижения – одна из наиболее актуальных. Издержки обращения оказывают влияние на основной финансовый результат деятельности – прибыль, так как в количественном выражении прибыль является остаточным показателем...
71394. Международное банковское обслуживание в сфере внешнеэкономической деятельности 2.49 MB
  Целью дипломной работы является разработка экономических подходов, способствующих совершенствованию банковского обслуживания внешнеэкономической деятельности на примере ОАО Банк ВТБ. В дипломной работе решается следующий перечень задач: охарактеризовать международную банковскую систему...
71396. Разработка предложения по совершенствованию информационной системы в отделе технической поддержки компании ООО «ИНСИС» 497.8 KB
  Мы живем в веке информационных технологий и всеобщей массовой компьютеризации. В наши дни информация является самым ходовым товаром. Информатизация общества - это глобальный социальный процесс, особенность которого состоит в том, что доминирующим видом деятельности...
71397. Ценностно-ролевая готовность выпускников ВУЗа и персонала промышленного предприятия к работе в условиях инноваций 64.57 KB
  Цель работы: Выявить характеристики ценностно-ролевовой готовности выпускников ВУЗа на примере финансового факультета и факультета социальных наук к работе в условиях инноваций. Задачи: Осуществить теоретический анализ современного...
71399. Взгдяд русского человека на традиционное семейное воспитание во Франции 73.7 KB
  Актуальность исследования определяется повышением интереса современного общества к семейному воспитанию так как значительное влияние на формирование полноценной личности ребенка имеет в первую очередь его семья. Проблемами семейного воспитания занимались как отечественные так и зарубежные педагоги.