Перегрузка бинарных операторов

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

{ действия, выполняемые применительно к классу

};

class A

{char c; int i;

public:

A(int I = 0, char C = NULL);

A(const A&);

A operator + (A);

friend A operator - (A,A);

A operator = (A);

};

A::A(int I, char C)

{ i = I; c = C;}

A::A(A const &obj)

{ i=obj.i;

c=obj.c;

}

A A::operator + (A obj)

{

A tmp;

tmp.i = this->i + obj.i; //a+b

if(c>obj.c) tmp.c = c+1;

else tmp.c = obj.c +1;

return tmp;

}

A operator - (A obj1, A obj2)

{

A tmp;

tmp.i = obj1.i-obj2.i;

if(obj1.c<obj2.c) tmp.c = obj1.c -1;

else tmp.c = obj2.c -1;

return tmp;

}

A A::operator = (A obj)

{

this->i=obj.i;

this->c=obj.c;

return *this;

}

void main()

{

A a(2,'a'), b(4,'b'), c, d;

c = a+b;

d=c=a-b;

}

Перегрузка унарных операторов.

14. Перегрузка операций ++ и ––

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

{ действия, выполняемые применительно к классу

};

class A

{ int a;

public:

A(int I = 0);

A(const A&);

A operator++();

A operator++(int);

friend A operator--(A &);

friend A operator--(A &,int );

A operator + (A);

};

A::A(int I)

{a = I;}

A::A(A const &obj)

{a=obj.a;}

A A::operator ++(int)

{ A tmp=*this; a++; return tmp;

}

A A::operator ++()

{ a++; return *this;

}

A operator --(A &obj)

{ obj.a--; return obj;

}

A operator --(A&obj,int)

{ A tmp=obj; obj.a--; return tmp;

}

A A::operator + (A obj)

{

A tmp;

tmp.a = this->a + obj.a;

return tmp;

}

void main()

{ A ob1(2),ob2(3);

ob1++ + ++ob2; //2+4

}

15.16.21.Перегрузка оператора().[].=

class A

{char *M; int len;

public:

A(const char * = "");

A(const A &);

~A();

char &operator[] (int);

A operator() (int,int);

A &operator=(const A &);

};

A::A(const char *s)

{ len = strlen(s); M = new char[len + 1]; strcpy(M, s);

}

A::A(const A &copy)

{ len = copy.len; M = new char[len + 1]; strcpy(M, copy.M);

}

A::~A()

{ delete [] M;

}

A A::operator () (int index, int len)

{ int j,i,len_new;

char x[100]="\0";

if(index>=0 && index<this->len)

{ if(this->len-index+1>=len) len_new = len;

else len_new = this->len-index+1;

for(j=0,i=index; j<len_new; i++,j++)

x[j]=M[i];

x[len_new] = '\0';

}

return A(x);

}

char &A::operator[] (int j)

{ assert(j >= 0 && j < len); return M[j];

}

A& A::operator=(const A &obj)

{ if(&obj!=this)

{

delete []M; this->len=obj.len; //new len stroki

M=new char[len+1]; strcpy(M, obj.M);

}

return *this;

}

void main()

{

A s01,s02;

s02=s01(3,10);

}

Перегрузка оператора ->.

Перегрузка оператора *.

class A

{ int a,b;

public:

A(int I = 0, int J = 0);

A(const A&);

A *operator -> () {return this;} //подменяется obj его адресом

A &operator * () {return *this;}

int min();

};

A::A(int I, int J)

{a = I; b = J;}

A::A(A const &obj)

{a=obj.a; b=obj.b;}

A::min()

{

if(a<b) return a;

else return b;

}

void main()

{

A obj;

A *p; p=&obj;

p->min();

obj->min(); //нужна была перегрузка. Станет так (&obj)->min();

}

Перегрузка оператора new.Перегрузка оператора delete.

void *operator new(size_t tip,int kol) // глобальная функция operator

{ cout << "глобальная функция NEW" <<endl;

return new char[tip*kol]; // вызов системной функции new

}

class cls

{ char a[40];

public:

cls(char *aa)

{ cout<<"конструктор класса cls"<<endl;

strcpy(a,aa);

}

~cls(){}

void *operator new(size_t,int);

void operator delete(void *);

};

void *cls::operator new(size_t tip,int n) // локальная функция operator

{ cout << "локальная функция " <<endl;

return new char[tip*n]; // вызов системной функции new

}

void cls::operator delete(void *p) // локальная функция operator

{ cout << "локальная функция DELETE" <<endl;

delete p; // вызов системной функции delete

}

void operator delete[](void *p) // глобальная функция operator

{ cout << "глобальная функция DELETE" <<endl;

delete p; // вызов системной функции delete

}

int main()

{ cls obj("перегрузка операторов NEW и DELETE");

float *ptr1;

ptr1=new (5) float; // вызов глобальной функции доопр. оператора new

delete [] ptr1; // вызов глобальной функции доопр. оператора delete

cls *ptr2=new (10) cls("aa"); // вызов локальной функции доопределения

// оператора new (из класса cls)

delete ptr2; // вызов локальной функции доопределения

return 0; // оператора delete (из класса cls)

}

Inline-функции.

Вызов функции означает переход к памяти, в которой расположен выполняемый код функции. Команда перехода занимает память и требует времени на ее выполнение, что иногда существенно превышает затраты памяти на хранение кода самой функции. Для таких функций целесообразно поместить код функции вместо выполнения перехода к функции. В этом случае при выполнении функции (обращении к ней) выполняется сразу ее код. Функции с такими свойствами являются встроенными. Иначе говоря, если описание

компоненты функции включается в класс, то такая функция называется встро-

енной. Например:

class stroka

{ char str[100];

public:

……..

int size()

{ for(int i=0; *(str+i); i++);

return i;

}

};

В описанном примере функция size() – встроенная. Если функция, объяв-

ленная в классе, а описанная за его пределами, должна быть встроенной, то она

описывается со спецификатором inline:

class stroka

{ char str[100];

public:

……..

int size();

};

inline int stroka ::size()

{ for(int i=0; str[i]; i++);

return i;

}

Спецификация inline может быть проигнорирована компилятором, по-

скольку иногда введение встроенных функций оказывается невозможным или

нежелательным.

Вложенные классы

Один класс может быть объявлен в другом классе, в этом случае внутрен-

ний класс называется вложенным:

class ext_class

{ class int_cls

{ · · ·

};

public:

· · ·

};

Класс int_cls является вложенным по отношению к классу ext_class

(внешний).

Доступ к компонентам вложенного класса, имеющим атрибут private,

возможен только из функций вложенного класса и из функций внешнего клас-

са, объявленных со спецификатором friend во вложенном классе.

#include <iostream>

using namespace std;

class cls1 // внешний класс

{ class cls2 // вложенный класс

{ int b; // все компоненты private для cls1 и cls2

cls2(int bb) : b(bb){} // конструктор класса cls2

};

public: // public секция для cls1

int a;

class cls3 // вложенный класс

{ int c; // private для cls1 и cls3

public: // public-секция для класса cls3

cls3(int cc): c(cc) {} // конструктор класса cls3

};

cls1(int aa): a(aa) {} // конструктор класса cls

};

void main()

{ cls1 aa(1980); // верно

//cls1::cls2 bb(456); // ошибка cls2 cannot access private

cls1::cls3 cc(789); // верно

cout << aa.a << endl; // верно

//cout << cc.c << endl; // ошибка 'c' : cannot access private member

// declared in class 'cls1::cls3'

}

Наши рекомендации