Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / C / C++ / Введение в язык C++ / Перегрузка Операций /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Класс Строка - Программирование от RIN.RU
Класс Строка

Вот довольно реалистичный пример класса string. В нем производится учет ссылок на строку с целью минимизировать копирование и в качестве констант применяются стандартные символьные строки C++.


#include
#include
 
 
class string {
struct srep {
char* s; // указатель на данные
int n; // счетчик ссылок
};
srep *p;
 
 
public:
string(char *); // string x = "abc"
string(); // string x;
string(string &); // string x = string ...
string& operator=(char *);
string& operator=(string &);
~string();
char& operator[](int i);
 
 
friend ostream& operator<<(ostream&, string&);
friend istream& operator>>(istream&, string&);
 
 
friend int operator==(string& x, char* s)
{return strcmp(x.p->s, s) == 0; }
 
 
friend int operator==(string& x, string& y)
{return strcmp(x.p->s, y.p->s) == 0; }
 
 
friend int operator!=(string& x, char* s)
{return strcmp(x.p->s, s) != 0; }
 
 
friend int operator!=(string& x, string& y)
{return strcmp(x.p->s, y.p->s) != 0; }
};


Конструкторы и деструкторы просты (как обычно):


string::string()
{
p = new srep;
p->s = 0;
p->n = 1;
}
 
 
string::string(char* s)
{
p = new srep;
p->s = new char[ strlen(s)+1 ];
strcpy(p->s, s);
p->n = 1;
}
 
 
string::string(string& x)
{
x.p->n++;
p = x.p;
}
 
 
string::~string()
{
if (--p->n == 0) {
delete p->s;
delete p;
}
}


Как обычно, операции присваивания очень похожи на конструкторы. Они должны обрабатывать очистку своего первого (левого) операнда:


string& string::operator=(char* s)
{
if (p->n > 1) { // разъединить себя
p-n--;
p = new srep;
}
else if (p->n == 1)
delete p->s;
 
 
p->s = new char[ strlen(s)+1 ];
strcpy(p->s, s);
p->n = 1;
return *this;
}


Благоразумно обеспечить, чтобы присваивание объекта самому себе работало правильно:


string& string::operator=(string& x)
{
x.p->n++;
if (--p->n == 0) {
delete p->s;
delete p;
}
p = x.p;
return *this;
}


Операция вывода задумана так, чтобы продемонстрировать применение учета ссылок. Она повторяет каждую вводимую строку (с помощью операции <<, которая определяется позднее):


ostream& operator<<(ostream& s, string& x)
{
return s << x.p->s << " [" << x.p->n << "]\n";
}


Операция ввода использует стандартную функцию ввода символьной строки (см. этот пункт).


istream& operator>>(istream& s, string& x)
{
char buf[256];
s >> buf;
x = buf;
cout << "echo: " << x << "\n";
return s;
}


Для доступа к отдельным символам предоставлена операция индексирования. Осуществляется проверка индекса:


void error(char* p)
{
cerr << p << "\n";
exit(1);
}
 
 
char& string::operator[](int i)
{
if (i<0 || strlen(p->s)s[i];
}


Головная программа просто немного опробует действия над строками. Она читает слова со ввода в строки, а потом эти строки печатает. Она продолжает это делать до тех пор, пока не распознает строку done, которая завершает сохранение слов в строках, или не встретит конец файла. После этого она печатает строки в обратном порядке и завершается.


main()
{
string x[100];
int n;
 
 
cout << "отсюда начнем\n";
for (n = 0; cin>>x[n]; n++) {
string y;
if (n==100) error("слишком много строк");
cout << (y = x[n]);
if (y=="done") break;
}
 
 
cout << "отсюда мы пройдем обратно\n";
for (int i=n-1; 0<=i; i--) cout << x[i];
}




 8  Комментарии к статье  8 8  Обсудить в чате

8  В тему

Введение

Функции Операции

Определяемое Преобразование Типа

Константы

Большие Объекты

Присваивание и Инициализация

Индексирование

Вызов Функции

Друзья и Члены

Предостережение

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь