Class string
{ char *str; // символьная строка
int size; // длина символьной строки
public:
string(); // конструктор по умолчанию
string(int n,char *s); // конструктор с параметрами
string(const string &); // конструктор копирования
~string(); // деструктор
friend string operator+(string, const string);
string &operator=(const string &);
void see();
};
string::string(){size=0; str=NULL;}; // конструктор по умолчанию
string::string(int n,char *s) // конструктор с параметрами
{ str=new char[size=n>=(strlen(s)+1)? n : strlen(s)+1];
strcpy(str,s);
}
string::string(const string &a) // описание конструктора копирования
{ str=new char[a.size+1]; // выделяем память под this->str (+1 под ’\0’)
strcpy(str,a.str); // копирование строки
size=strlen(str)+1;
}
string::~string(){ if(str) delete [] str;}
string operator+(string s1, const string s2) // перегрузка операции +
{ string ss;
if(!ss.str) ss.str=new char[ss.size=strlen(s1.str)+strlen(s2.str)+2];
for(int i=0; ss.str[i]=s1.str[i]; i++); // перезапись символа ’\0’
ss.str[i]=' '; // удаление ’\0’
for(int j=0; ss.str[i+1]=s2.str[j]; i++,j++); // дозапись второй строки
return ss;
}
string &string::operator =(const string &st) // перегрузка операции =
{ if(this!=&st) // проверка, не копирование ли объекта в себя
{ delete str; // освобождаем память старой строки
str=new char[size=st.size];// выделяем память под новую строку
strcpy(str,st.str);
}
return *this;
}
void string::see()
{ cout << this->str << endl;
}
int main()
{ string s1(10,"язык"), s2(30,"программирования"), s3(30," ");
s1.see();
s2.see();
string s4=s1; // это только вызов конструктора копирования
s4.see();
string s5(s1); // прямой вызов конструктора копирования
s5.see();
s1+s2; // перегрузка + (вызов функции operator +)
s1.see();
s3=s2; // перегрузка = (вызов функции operator =)
s3.see();
s3=s1+s2; //перегрузка операции + , затем операции =
s3.see();
return 0;
}
Результаты работы программы:
язык
программирования
язык
язык
программирования
язык программирования
Инструкция string s4=s1 только вызывает конструктор копирования для объекта s4. В инструкции string s5(s1) выполняется прямой вызов конструктора копирования для объекта s5. Выполнение инструкции s1+s2 приводит к двум вызовам конструктора копирования (вначале для копирования в стек объекта s2, затем s1). После этого выполняется вызов функции operator+ для инструкции s1+s2. При выходе из функции (инструкция return ss) вновь выполняется вызов конструктора копирования. При выполнении инструкции s3=s2 конструктор копирования для копирования объекта s2 в стек не вызывался, так как параметр в operator= передан (и возвращен) по ссылке.
5.2.5. Перегрузка оператора []
Как было отмечено выше, функция operator может быть с успехом использована для доопределения операторов С++ (в основном арифметические, логические и операторы отношения). В то же время в С++ существуют некоторые операторы, не входящие в число перечисленных, но которые полезно перегружать. К ним относится оператор []. Его необходимо перегружать с помощью компоненты-функции, использование friend-функции запрещено. Общая форма функции operator[]() имеет вид
тип_возвр_значения имя_класса::operator [](int i)
{ тело функции}
Параметр функции необязательно должен иметь тип int , но он использован, так как operator[] в основном применяется для индексации. Рассмотрим пример программы с использованием перегрузки операции []:
#include <iostream>
using namespace std;