Класс Строка

Вот довольно реалистичный пример класса 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 cha

r[ 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];


}

Сохранить в соц. сетях:
Обсуждение:
comments powered by Disqus

Название реферата: Класс Строка

Слов:545
Символов:5072
Размер:9.91 Кб.