Слайд 2Перегрузка операторов
используется для улучшения читаемости и упрощения кода
общий вид:
тип имя_класса::operator#(параметры) {…}
Можно перегружать
все кроме
:: .* ?
Операторная функция может быть членом класса или «другом»
Слайд 3С использованием функций-членов
Операторная функция принимает на один параметр меньше
Объект, стоящий слева от
оператора вызывает операторную функцию и передается ей не явно (через this)
Объект, стоящий справа передается через параметр
Слайд 4Пример
class three_d {
int x, y, z; // 3-D coordinates
public:
three_d() {
x = y = z = 0; }
three_d(int i, int j, int k) {x = i; y = j; z = k; }
three_d operator+(three_d op2); // op1 is implied
three_d operator=(three_d op2); // op1 is implied
void show() { cout << x << ", "; cout << y << ", "; cout << z << "\n"; }
};
three_d three_d::operator+(three_d op2) {
three_d temp;
temp.x = x + op2.x;
temp.y = y + op2.y;
temp.z = z + op2.z;.
return temp;
}
three_d three_d::operator=(three_d op2) {
x = op2.x; y = op2.y; z = op2.z;
return *this;
}
void main() {
three_d a(1, 2, 3), b(10, 10, 10), c;
a.show(); b.show();
c = a + b; c.show();
c = a + b + c; c.show();
c = b = a;
c.show(); b.show();
}
Слайд 5Перегрузка унарных операторов
class three_d {
int x, y, z; // 3-D coordinates
public:
three_d() { x = y = z = 0; }
three_d(int i, int j, int k) {x = i; y = j; z = k; }
three_d operator+(three_d op2);
three_d operator=(three_d op2);
three_d operator++(); // prefix version of ++
void show() { cout << x << ", "; cout << y << ", ";
cout << z << "\n"; }
} ;
three_d three_d::operator++() {
x++; y++; z++;
return *this;
}
void main() {
three_d a(1, 2, 3), b(10, 10, 10), c;
a.show(); b.show();
c = a + b; c.show();
c = a + b + c; c.show();
c = b = a; c.show(); b.show();
++c;
c.show();
}
Слайд 6Постфиксная форма
three_d three_d::operator++(int notused) {
three_d temp = *this; // сохраняем
x++;
y++;
z++;
return temp; // возвращаем не измененную
}
Слайд 7Операторная функция – не член класса
Бинарные операции имеют 2 параметра
Унарные операции имеют
1 параметр
Часто объявляются «друзьями»
Нельзя перегружать:
= () [] ->
Слайд 8Пример
class three_d {
int x, y, z; // 3-D coordinates
public:
three_d() {
x = y = z = 0; }
three_d(int i, int j, int k) { x = i; y = j; z = k;}
friend three_d operator+(three_d op1, three_d op2);
three_d operator=(three_d op2); // op2 is implied
void show() { cout << x << ", "; cout << y << ", ";
cout << z << "\n";}
} ;
three_d operator+(three_d op1, three_d op2) {
three_d temp;
temp.x = op1.x + op2.x; temp.y = op1.y + op2.y;
temp.z = op1.z + op2.z; return temp;
}
void main() {
three_d a(1, 2, 3), b(10, 10, 10), c;
a.show(); b.show();
c = a + b;
c.show();
c = a + b + c;
c.show();
c = b = a; c.show(); b.show();
}
Слайд 9Перегрузка
class CL {
public:
int count;
CL operator=(CL obj);
friend CL operator+(CL ob,
int i);
friend CL operator+(int i, CL ob);
};
CL CL::operator=(CL obj) { count = obj.count; return *this; }
CL operator+(CL ob, int i) { CL temp; temp.count = ob.count + i; return temp; }
CL operator+(int i, CL ob) { CL temp; temp.count = ob.count + i; return temp; }
int main() {
CL O;
O.count = 10;
cout << O.count << " "; // 10
O = 10 + O;
cout << O.count << " "; // 20
O = O + 12;
cout << O.count; // 32
return 0;
}
Слайд 10Перегрузка унарных операторов
Работать не будет:
three_d operator++(three_d op1)
{
op1.x++;
op1.y++;
op1.z++;
return op1;
}
Слайд 11Перегрузка унарных операторов
class three_d {
int x, y, z; // 3-D coordinates
public:
three_d() { x = y = z = 0; }
three_d(int i, int j, int k) {x = i; y = j; z = k; }
friend three_d operator+(three_d op1, three_d op2);
three_d operator=(three_d op2);
friend three_d operator++(three_d &op1);
friend three_d operator++(three_d &op1, int notused);
void show() ;
} ;
three_d operator++(three_d &op1) {
op1.x++;
op1.y++;
op1.z++;
return op1;
}
three_d operator++(three_d &op1, int notused) {
three_d temp = op1;
op1.x++;
op1.y++;
op1.z++;
return temp;
}
Слайд 12Перегрузка оператора присваивания
class sample {
char *s;
public:
sample() { s = 0;
}
sample(const sample &ob) { s = new char[strlen(ob.s)+1];
strcpy(s, ob.s);}
~sample( ) { if(s) delete [] s;}
void show() { cout << s << "\n"; }
void set(char *str) { s = new char[strlen(str)+1];
strcpy(s, str);}
};
sample input(){
char instr[80];
sample str;
cout << "Enter a string: "; cin >> instr;
str.set(instr);
return str;
}
void main() {
sample ob;
ob = input(); // ошибка!!!!
ob.show();
}
Слайд 13Перегрузка оператора присваивания
Решение проблемы: перегрузка оператора присваивания:
sample sample::operator=(sample &ob)
{
if(strlen(ob.s) > strlen(s))
{
delete [ ] s;
s = new char[strlen(ob.s)+1];
}
strcpy(s, ob.s);
return *this;
}
Слайд 14Перегрузка оператора [ ]
Оператор [ ] перегружается как бинарный
Только для класса
Только как
член класса
Общий вид:
тип имя_класса::operator[]( int индекс ) {…}
Для того, чтобы выражение с [] могло стоять слева от оператора присваивания, операторная функция должна возвращать ссылку на тип:
тип& имя_класса::operator[]( int индекс ) {…}
Слайд 15Пример: безопасный массив
const int SIZE = 3;
class atype {
int a[SIZE];
public:
atype()
{ register int i; for(i=0; i int &operator[](int i);
};
int &atype::operator[](int i) {
if( i<0 || i> SIZE-1) {
cout << "\nIndex out-of-bounds.\n"; exit(1); }
return a[i];
}
void main() {
atype ob;
cout << ob[2]; cout << " ";
ob[2] = 25;
cout << ob[2];
ob[3] = 44; // ошибка!!
}
Слайд 16Перегрузка оператора ( )
class three_d {
int x, y, z; // 3-D
coordinates
public:
three_d() { x = y = z = 0; }
three_d(int i, int j, int k) {x = i; y = j; z = k; }
three_d operator()(int a, int b, int c);
void show() { cout << x << ", "; cout << y << ", "; cout << z << "\n";}
};
three_d three_d::operator()(int a, int b, int c) {
three_d temp;
temp.x = x + a; temp.y = y + b; temp.z = z + c;
return temp;
}
int main() {
three_d ob1(1, 2, 3), ob2;
ob2 = ob1(10, 11, 12); // вызов operator()
cout << "ob1: "; ob1.show();
cout << "ob2: "; ob2.show();
return 0;
}