Класс Строка

Класс Строка

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

  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

{

  return s
s n

}

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

istream& operator>>(istream& s,
string& x)

{

char buf[256];

s >> buf;

x = buf;

cout

return s;

}

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

void error(char* p)

{

  cerr

  exit(1);

}

char& string::operator[](int i)

{

  if (is)s[i];

}

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

main()

{

  string x[100];

  int n;

  cout

  for (n = 0;
cin>>x[n]; n++) {

      string y;

      if
(n==100) error(“слишком много строк”);

      cout

      if (y==”done”) break;

  }

  cout

  for (int i=n-1; 0

}
Список литературы

Для подготовки данной работы были использованы материалы
с сайта http://www.realcoding.net