Использование дружественных оператор-функций

В дружественную функцию не передается указатель 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;

}