Класс Строка

СОДЕРЖАНИЕ: Вот довольно реалистичный пример класса string. В нем производится учет ссылок на строку с целью минимизировать копирование и в качестве констант применяются стандартные символьные строки C++.

Вот довольно реалистичный пример класса 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 (i0 || strlen(p-s)s[i];

}

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

main()

{

string x[100];

int n;

cout отсюданачнем\n;

for (n = 0; cinx[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];

}

Скачать архив с текстом документа