- •ПЕРЕГРУЗКА ОПЕРАЦИЙ
- •Можно перегружать:
- •При создании описания класса существует две возможности определения операций:
- •Если унарная перегруженная операция реализована как метод класса, то у него нет параметров.
- •void operator-(Complex c1);
- •Например, X::operator T() – преобразует X в T.
- •Примечание.
- •int main()
- •tiny tiny::operator--(int){ v--;
- •Большие объекты
- •Указатели для этой цели использовать нельзя, т.к. невозможно переопределить интерпретацию операции, если она
- •Пример. Определение класса string.
- •string::string(const string& a)
- •delete s2; delete s1; delete s; return 0;
ПЕРЕГРУЗКА ОПЕРАЦИЙ
Перегрузка операторов позволяет определять действия для объектов класса в выражениях, использующих обычные операторы, такие как сложение (+) или вычитание (-).
То с помощью перегрузки можно задать новую интерпретацию стандартным операциям применительно к объектам классов.
Общий вид перегруженной операции:
<имя_класса> operator op(<имя_класса > a, < имя_класса > b)
Можно перегружать: |
|
|
|
|
|||
* |
/ |
+ |
- |
% |
^ |
& |
| |
~ |
! |
, |
= |
< |
> |
<= |
>= |
++ |
-- |
<< |
>> |
== |
!= |
&& |
|| |
*= |
/= |
%= |
^= |
&= |
|= |
+= |
-= |
<<= |
>>= |
-> |
->* |
[] |
() |
new |
dele |
|
|
|
|
|
|
|
te |
а также: new[], delete[] Нельзя перегружать:
. |
.* |
:: |
?: |
sizeof |
При создании описания класса существует две возможности определения операций:
1)в виде функции класса;
2)в виде дружественной функции.
Если бинарная перегруженная операция реализована как метод класса, то ее первым операндом является объект, для которого вызывается метод (оператор), а второй член операции передаётся как аргумент метода.
В случае дружественной функции ей передаются оба операнда как аргументы.
Если унарная перегруженная операция реализована как метод класса, то у него нет параметров.
Если унарная перегруженная операция реализована как дружественная функция, то у неё один аргумент.
Ограничения реализации перегрузки операций в C++.
С++ «не понимает» семантики перегруженного оператора.
С++ не может выводить сложные операторы из простых (например, «+=» из «+» и «=»).
Нельзя изобретать новые операторы.
Пример. Перегрузка операций «+» и «-» для комплексных чисел
class Complex {
double real, imag; public:
Complex(double aReal=0.0, double aImag=0.0): real(aReal), imag(aImag) {};
double GetReal() {return real;}
double GetImag() {return imag;}
friend Complex operator+(Complex c1, Complex c2);
friend Complex operator*(Complex c1, Complex c2);
void operator-(Complex c1);
friend ostream &operator<<(ostream&, const Complex&);
friend istream &operator>>(istream&, Complex&);
};
Complex operator*(Complex c1, Complex c2) { double rnew,inew; rnew=c1.real*c2.real-c1.imag*c2.imag; inew=c1.real*c2.imag+c1.imag*c2.real; return Complex(rnew, inew);
}
Complex operator+(Complex c1, Complex c2) { return Complex(c1.real+c2.real,
c1.imag+c2.imag);
}
void Complex::operator -(Complex c1) { real-=c1.real;
imag-=c1.imag;
}
istream &operator>>(istream &input, Complex& c1) {
cout<<"Введите действительную часть числа:";
input>>c1.real;
cout<<"Введите мнимую часть числа:"; input>>c1.imag;
return input;
}
ostream &operator<<(ostream& output, const Complex& c1)
{
output<<c1.real; if (c1.imag)
{
if (c1.imag>0) output<<"+";
output<<c1.imag<<"*i";
}
output<<endl; return output;
}
int main() {
Complex a(1.0,2.0), b(3.0,4.0); a=a+b;
cout<<a;
cout<<b;
b-a; cout<<a; cout<<b;
a.operator -(b); cout<<a; cout<<b;
Complex c = operator+(a,b); cout<<c;
Complex d=a*b+c; cout<<d;
Complex e=a*(b+c); cout<<e;
cin>>a;
cout<<a*2; return 0;
}
Примечание 1. Из перегруженных операторов можно составлять арифметические выражения по существующим правилам; приоритет операций сохраняется.
Примечание 2. Выражение a*2 возможно из-за наличия конструктора Complex(double=0.0, double=0.0); a*2 означает operator*(a, complex(double(2), double(0))) .
Операции преобразования
Неявные преобразования от пользовательского типа к основному невозможны.
Поэтому в классе необходимо определить операторную функцию приведения типа класс к необходимому типу.