Перегрузка бинарных операторов
тип_возвр_значения имя_класса :: 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 ©)
{ 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'
}