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;

}


 

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

43002. Динамический и силовой анализ механизма 99.5 KB
  Динамический анализ механизма включает в себя определение движущего момента такого, чтобы звенья механизма двигались с заданными скоростями при заданных нагрузках и массах действующих на механизм. Формула для определения движущего момента
43003. Расчет заготовки коробчатой формы 364.5 KB
  Основной критерий оборудования − это номинальное усилие пресса. 1 операция Вырубка заготовки При вырубке круглой заготовки необходимо учитывать следующие усилия: Pвыр− усилие затрачиваемое на вырубку заготовки пуансоном; Рпрот− усилие затрачиваемое на проталкивание заготовки пуансоном через отверстие в матрице; Ртр− усилие затрачиваемое на трение отхода о пуансон. Усилие операции: Pоп = Pвыр Рпрот Ртр. Усилие вырубки заготовки: k=1113 коэффициент учитывающий притупление режущих кромок неравномерность зазора...
43004. Создание проектной базы для внедрения в отечественную строительную практику комплектной системы KNAUF, обеспечивающей "сухой" (без использования мокрых процессов) способ высококачественной отделки помещений 2.22 MB
  Сборные гипсокартонные перегородки системы KNUF применяются как внутренние ограждающие конструкции помещений с сухим нормальным и влажным режимом см. Перегородки и узлы разработанные в настоящей серии предназначены для применения в жилых общественных и производственных зданиях: любых конструктивных систем и типов; любого уровня ответственности включая повышенный; любой степени огнестойкости включая Iую степень; различной этажности с высотой зданий не более 60 м; возводимых в ветровых районах до Vго включительно;...
43005. Проектування промислового будинку, район будівництва, м.Кременчук 183.5 KB
  Опис планувальнопросторового рішення будинку. Вихідні дані Для проектування промислового будинку в завданні зазначається: район будівництва м. Перший етап: вивчення завдання методичних вказівок літератури розробка варіантів їх обємнопланувальних рішень розрахунок адміністративнопобутових приміщень вибір конструкцій виробничого цеху розробка ескізних рішень промислового будинку які затверджуються викладачем. Маркувальний план виробничого будинку.
43006. Технологическая карта на многоэтажное каркасное здание 435 KB
  Для правильного и эффективного решения всех вопросов, касающихся технологии производства монолитных и монтажных работ, выполнен оптимальный выбор методов и способов производства работ: метод производства монолитных работ - раздельный, направление развития процесса - по горизонтали вдоль здания. Здание условно поделено на две захватки, гранича которых проходит через ось 7. Монтаж стеновых панелей производится параллельно с возведение каркаса здания, с отставанием на одну захватку.
43007. Разработка направления и совершенствования логистической деятельности и процесса транспортировки в фокусном звене цепи поставок 1.02 MB
  Возникает необходимость регулирования всей системы движения товаров при этом эффективность цепи поставок определяется уровнем организационного оформления хозяйственных связей всех участников товародвижения. Изучается транспортировка в цепи поставок с целью ознакомления с логистическими особенностями отдельных видов транспорта зависимостью логистических издержек в цепи поставок от параметров транспортировки способами обоснования оптимальных схем доставки грузов методами рациональной организации перевозок основными путями повышения уровня...
43008. Организация и обслуживание банкета по поводу международного женского дня 8 марта на 50 человек 772.5 KB
  В настоящее время ресторанное хозяйство развивается по различным направлениям. Появляется большое количество ресторанов с национальной кухней, появляются новые виды предприятий ресторанного хозяйства (пабы, суши-бары), в наши дни предприятия ресторанного хозяйства оснащаются автоматизированными системами ведения счетов, появляются новые профессии (сомелье, хостесс) и, в конце концов, современное предприятие ресторанного хозяйства становится местом красивого, приятного времяпрепровождения.
43010. Расчет УНЧ на БПТ 221 KB
  Принципиальная схема каскада. Составив блоксхему усилителя выбирают принципиальные схемы входного и выходного устройств реостатноемкостные трансформаторные каскада мощного усилителя одноактный двухтактный трансформаторный бестрансформаторный каскадов предварительного усиления с прямой связью реостатный трансформаторный инверсный и т. После чего составляют принципиальную ориентировочную схему усилителя и распределяют заданные частотные искажения по цепям и каскадам вносящим эти искажения. Расчет усилителя производят начиная...