Использование дружественных оператор-функций
В дружественную функцию не передается указатель this, поэтому при перегрузке для унарного оператора в оператор-функцию передается один параметр, для бинарного – два. Оператор присваивания не может быть дружественной функцией, а только членом класса. В следующем примере рассматривается использование дружественных оператор-функций +, *, /, <<, >> для класса Complex.
#include <iostream.h>//пример 29
#include <stdio.h>
#include <conio.h>
class Complex {
double re, im;
public:
Complex (double r=0,double i=0)//конструктор
{re=r;im=i;}
friend Complex operator+(Complex, Complex);
friend Complex operator*(Complex, Complex);
friend Complex operator/(Complex, Complex);
friend ostream & operator<<(ostream &stream, Complex ob);
friend istream & operator>>(istream &stream, Complex ob);
};
ostream &operator<<(ostream &stream, Complex ob) {
stream <<"("<< ob.re << ", " << ob.im <<")"<< '\n';
return stream;
}
istream &operator>>(istream &stream, Complex &ob){
//double a,b;
//scanf("(%lf,%lf)",&a,&b);
//ob=Complex(a,b);
stream >> ob.re >> ob.im;
return stream;
}
Complex operator+(Complex a1, Complex a2){
return Complex(a1.re+a2.re,a1.im+a2.im);
}
Complex operator*(Complex a1, Complex a2){
return Complex(a1.re*a2.re-a1.im*a2.im, a1.re*a2.im+a1.im*a2.re);
}
Complex operator/(Complex a1, Complex a2){
double r=a2.re,i=a2.im;
double tr=r*r+i*i;
return Complex((a1.re*r+a2.im*i)/tr,(a1.im*r-a1.re*i)/tr);
}
int main(){
Complex a(1.,2.),b(2.,2.),c;
c=a+b;
cout<<c<<a*b<<a/b<<endl;
cout<<"Enter complex number:";
cin>>c;
cout<<c;
while(!kbhit());
return 0;
}
Вывод:
(3,4) (-2,6) (0.75,0.25)
//Enter complex number:(5,7)<ввод>
//(5,7)
Операторы-функции, объявленные как friendвнутри класса Complex, не являются членами класса, но подобно им они имеют доступ к закрытым элементам класса. Объект класса при этом должен быть параметром, иначе функция не знает, с каким объектом работать (this не передается). В C++ используется определенный в файле complex.h библиотечный класс complex, который представляет тип данных, включающий и другие операции над комплексными числами.
Рассмотрим еще один пример использования операций при создании бинарного дерева.
#include <iostream.h>//пример 29а
#include <conio.h>
struct Node{ // узел дерева
char info; // информационная часть узла
int count; // число повторений информации
Node* nextl,*nextr; // указатели на левое и правое поддеревья
Node(char newinfo='a') {
info=newinfo;
nextl=nextr=0;
count=1;}
};
class Tree { //класс дерево
public:
Node* root; //указатель на корень дерева
Tree() { // конструктор формирует пустое дерево
root=0;}
void push(Node * &wer, char dat) { // добавление элемента
if(wer==0){
wer = new Node;
wer->nextl=0;
wer->nextr=0;
wer->info = dat;}
else if(dat<wer->info) push(wer->nextl, dat);
else if(dat>wer->info) push(wer->nextr, dat);
else wer->count++; //root=wer;
}
void insert(char dat) { // вставка в дерево
if (root==0) root=new Node(dat);
else push(root, dat);
}
void look(node *&wer) { // обход дерева
if (wer!=0) {
look(wer->nextl);
cout<<" "<<wer->info<<" - "<<wer->count;
look(wer->nextr);
}
}
Tree operator+(char c) {
Tree temp;
insert(c);
temp.root=root;
return temp;}
Tree operator=(Tree ob2) {
root=ob2.root;
return *this;}
friend ostream &operator<<(ostream &stream,Tree ob);
};
ostream &operator<<(ostream &stream,tree ob) {
ob.look(ob.root);
return stream;}
int main(){
Tree q;
Node *n;
char c,key='a' ;
do {
cout << "Input a char until *: ";
cin >> c;
q.insert(c); }//ввод
while(c != '*');
q.look(q.root); //просмотр
cout << "Input a char :";
cin>>c;
q=q+c;
cout<<q;
while(!kbhit());
return 0;
}