Язык программирования C++ для профессионалов




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


Теперь можно привести более осмысленный вариант класса 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; }




Содержание  Назад  Вперед