Class stroka
Void main ()
{
Complex c1 (1, 2); // создание объекта c1
Complex c2 (3, 4); // создание объекта c2
Complex c3 = - c2; // копирование в c3 результата вызова c2.operator-(); Complex c4 =c2-c1; // копирование в c4 результата вызова c2.operator- (с1);
Complex c5= c2+c1 // копирование в c5 результата вызова operator+(с2,с1);
Видим в двух последних строках, что синтаксис правил использования функций - перегрузки операций, определенных как методы класса или как друзья класса, совершенно одинаков.
Однако определение операций-функций как дружественных создает преимущество в смысле симметрии и, главное, в тех случаях, когда для выполнения действий над операндами требуется преобразование типа операндов.
Дело в том, что компилятор автоматически выполняет преобразование типа для аргументов функций, но не для объекта, для которого вызывается функция-член.
Если функция-оператор (другое название операции - функции) реализуется как друг и получает оба аргумента как параметры функции, то компилятор выполняет автоматическое преобразование типов двух аргументов операции.
|
|
Пример:
1. #include<string.h>
#include <iostream.h>
{ char*ch; // указатель на строку на символьный массив
int len; // длина строки
public:
stroka(char*cch) // конструктор1
{ len = strlen(cch); ch=new char [len+1]; strcpy (ch,cch); }
stroka(int N=20) // конструктор 2
{ ch = new char[N+1]; len=0; ch[0]='\0';}
int len_str(void) { return len;} // возвращает длину строки
char * string (void) {return ch;} // возвращает указатель на строку
void vivod () // выводит данные
{ cout<< "строка: " <<ch <<", длина строки="<<len;};
~stroka() // деструктор
{ delete [ ]ch; }
stroka& operator+ (stroka&); //прототип функции-оператора - метод
};
stroka& stroka::operator+ (stroka&A)
{ int N = len+ A.len_str();
stroka*ptr=new stroka(N); // создаем динамический объект
// выделяем память на суммарную строку
strcpy(ptr->string(), ch); // копируем в новую строку первую строку
strcat (ptr->string(), A.string ()); // присоединяем к ней и вторую строку
return *ptr; // возвращаем объект, а не указатель на объект
}
{
stroka X ("Миру -"); // объявлена три объекта
stroka Y(" мир!");
stroka Z;
Z=X+Y; // эквивалентно Z =X.operator + (Y);
Z.vivod();
(X+Y).vivod();
}
2. #include<string.h>
#include <iostream.h>
class stroka {
char*ch; // указатель на строку на символьный массив
int len; // длина строки
public:
stroka(char*cch) // конструктор1
{ len = strlen(cch); ch=new char [len+1];
strcpy (ch,cch); }
stroka(int N=20) // конструктор 2
{ ch = new char[N+1];
len=0;
ch[0]='\0';}
int len_str(void) { return len;} // возвращает длину строки
char * string (void) {return ch;} // возвращает указатель на строку
void vivod () // выводит данные
{ cout<< "строка: " <<ch <<", длина строки="<<len;};
~stroka() // деструктор
{ delete [ ]ch; }
friend stroka& operator+(stroka&, stroka&); //функция-операция друг
};
stroka& operator+(stroka&A, stroka & B)
{ int N = A.len_str ()+ B.len_str();
stroka*ptr=new stroka(N);
// выделяем память на суммарную строку
|
|
strcpy(ptr->string(), A.string());// копируем в новую строку первуюстроку
strcat(ptr->string(), B.string ()); // присоединяем к ней и вторую строку
return *ptr; //возвращаем оъект, а не указатель на объект (разыменовали)
}