Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КРАТКИЙ ОБЗОР С.doc
Скачиваний:
1
Добавлен:
26.10.2018
Размер:
2.11 Mб
Скачать

7.11 Строковый класс

      Теперь можно привести более осмысленный вариант класса string.       В нем подсчитывается число ссылок на строку, чтобы минимизировать       копирование, и используются как константы стандартные строки C++.       #include <iostream.h>       #include <string.h>       class string {       struct srep {       char* s; // указатель на строку       int n; // счетчик числа ссылок       srep() { n = 1; }       };       srep *p;       public:       string(const char *); // string x = "abc"       string(); // string x;       string(const string &); // string x = string ...       string& operator=(const char *);       string& operator=(const string &);       ~string();       char& operator[](int i);       friend ostream& operator<<(ostream&, const string&);       friend istream& operator>>(istream&, string&);       friend int operator==(const string &x, const char *s)       { return strcmp(x.p->s,s) == 0; }       friend int operator==(const string &x, const string &y)       { return strcmp(x.p->s,y.p->s) == 0; }       friend int operator!=(const string &x, const char *s)       { return strcmp(x.p->s,s) != 0; }       friend int operator!=(const string &x, const string &y)       { return strcmp(x.p->s,y.p->s) != 0; }       }; Конструкторы и деструкторы тривиальны:       string::string()       {       p = new srep;       p->s = 0;       }       string::string(const string& x)       {       x.p->n++;       p = x.p;       }       string::string(const char* s)       {       p = new srep;       p->s = new char[ strlen(s)+1 ];       strcpy(p->s, s);       }       string::~string()       {       if (--p->n == 0) {       delete[] p->s;       delete p;       }       }       Как и всегда операции присваивания похожи на конструкторы. В них       нужно позаботиться об удалении первого операнда, задающего левую       часть присваивания:       string& string::operator=(const char* s)       {       if (p->n > 1) { // отсоединяемся от старой строки       p->n--;       p = new srep;       }       else // освобождаем строку со старым значением       delete[] p->s;       p->s = new char[ strlen(s)+1 ];       strcpy(p->s, s);       return *this;       }       string& string::operator=(const string& x)       {       x.p->n++; // защита от случая ``st = st''       if (--p->n == 0) {       delete[] p->s;       delete p       }       p = x.p;       return *this;       }       Операция вывода показывает как используется счетчик числа ссылок.       Она сопровождает как эхо каждую введенную строку (ввод происходит       с помощью операции << , приведенной ниже):       ostream& operator<<(ostream& s, const string& x)       {       return s << x.p->s << " [" << x.p->n << "]\n";       }       Операция ввода происходит с помощью стандартной функции ввода       символьной строки ($$10.3.1):       istream& operator>>(istream& s, string& x)       {       char buf[256];       s >> buf; // ненадежно: возможно переполнение buf       // правильное решение см. в $$10.3.1       x = buf;       cout << "echo: " << x << '\n';       return s;       }       Операция индексации нужна для доступа к отдельным символам.       Индекс контролируется:       void error(const char* p)       {       cerr << p << '\n';       exit(1);       }       char& string::operator[](int i)       {       if (i<0 || strlen(p->s)<i) error("недопустимое значение индекса");       return p->s[i];       }       В основной программе просто даны несколько примеров применения       строковых операций. Слова из входного потока читаются в строки,       а затем строки печатаются. Это продолжается до тех пор, пока не       будет обнаружена строка done, или закончатся строки для записи       слов, или закончится входной поток. Затем печатаются все строки       в обратном порядке и программа завершается.       int main()       {       string x[100];       int n;       cout << " здесь начало \n";       for ( n = 0; cin>>x[n]; n++) {       if (n==100) {       error("слишком много слов");       return 99;       }       string y;       cout << (y = x[n]);       if (y == "done") break;       }       cout << "теперь мы идем по словам в обратном порядке \n";       for (int i=n-1; 0<=i; i--) cout << x[i];       return 0;       }