{re=r, im=i;}
friend complex operator+(complex,complex);
};
Void main()
{complex a=complex(1,3.1);
complex b=complex(1.2,2);
complex c=b;
a=b+c; //(1)
c=a+complex(1,2);} //(2)
complex operator+(complex a,complex b)
{complex c;
c.re=a.re+b.re;
c.im=a.im+b.im;
return c;}
Замiсть (1)–(2) можна записати:
а=operator+(b,c);
c=operator(a,complex(1,2));
Бачимо, що, оголосивши перевантажену операцію + як дружню функцію до класу, можемо вільно використовувати значок + відносно екземплярів класу. Причому в точках, де розташована перевантажена операція, відбувається виклик відповідної функції (у даному випадку – operatop+). Очевидно, що компілятор буде розрізняти + перевантажений і + звичайний. Якщо десь буде фігурувати звичайний арифметичний вираз, то жодних конфліктів не виникне. Іншими словами, перевантажуючи операції, ми ніби розширюємо поле їх дії на відповідні екземпляри класів. Порожній void -конструктор класу complex необхідний для коректного оголошення екземпляра класу c у функції operator+().
Перепишемо приклад так, щоб перевантажена операція була членом класу:
class complex {
public:
double re,im;
complex(){};
Complex(double r,double i)
|
|
{re=r;im=i;}
complex operator+(complex);}
complex complex::operator+(complex a)
{
a.re+=re;
a.im+=im;
return a;}
Бачимо, що в перевантаженій операції +, на відміну від попереднього прикладу, є один формальний параметр типу complex. Другий просто не потрібен. Адже другим параметром виступає покажчик на об'єкт this, для якого викликається функція-член.
Для перевантажених операцій обов’язково має зберігатися така сама кількість операндів, яка була й у базовій операції. Наприклад:
class x {
friend x operator – (x);
Friend x operator – (x,x)
Friend x operator – (); //помилка
friend x operator – (x,x,x); //помилка};
У першій і другій перевантаженій операціях кількість операндів нормальна: перший мінус – унарний, другий – бінарний. У третій і четвертій є помилка, оскільки не існує базових операцій з відповідною кількістю операндів.
Згадаємо особливість мови С (С++), яка полягає у відсутності можливості роботи зі складеними типами даних як з одним цілим. Використовуючи перевантаження, ми можемо самі створювати потрібні типи. Розглянемо, наприклад, клас
class string {
private:
char value[100];
public:
string(){value[0]=0;}
string(const char*s)
{strcpy(value,s);}
long GetValue(void){return atol(value);}
friend long operator+(string a,string b);
friend long operator – (string a,string b);};
Main()
{
string a="1234";
string b="4321";
cout<<"\na+b+6="<<(a+b+6);
cout<<"\na-b+10="<<(a-b+10)<<'\n';}
long operator+(string a,string b)
{return(atol(a.value)+atol(b.value));}