Главная->Інформатика та програмування->Содержание->Определенные пользователем типы строк

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 7) онлайн

Определенные пользователем типы строк

При использовании строкового типа в C++ иногда возникают проблемы. Одна из них заключается в том, что вы не можете использовать совершенно разумное выражение

strDest = strSrc;

для установки равенства одной строки другой. (В некоторых языках, таких, как BASIC, это замечательно работает.) В стандартном классе C++ string, который мы рассмотрим в следующем разделе, эта проблема решена, но на данный момент давайте посмотрим, как мы сможем использовать технологии ООП для само- стоятельного решения этой проблемы. Создадим наш собственный класс string, что даст нам возможность представлять строки как объекты класса, который прольет свет на операции стандартного класса string.

Если мы определим наш собственный тип строк, используя класс, то мы смо- жем использовать выражения присваивания. (Многие другие операции со стро- ками, такие, как объединение, могут быть также упрощены, но мы должны по- дождать до главы 8 «Перегрузка операций», чтобы увидеть, как это сделать.)

Программа STROBJ создает класс String. (Не путайте этот самопальный класс String со стандартным встроенным классом string, название которого начинается с маленькой буквы 's'.) Приведем листинг:

// strobj.cpp

// строка как класс

#include <iostream>

#include <cstring>

using namespace std;

///////////////////////////////////////////////////////////

class String

{

  private:

    enum { SZ = 80 };        // максимальный размер строки

    char str [ SZ ];          // сама строка

  public:

    String ( ) // конструктор без параметров

      { str [ 0 ] = '\0'; }

    String ( char s [ ] )     // конструктор с одним параметром

      { strcpy ( str, s ); }

    void display ( )          // показ строки

      { cout << str; }

    void concat ( String s2 ) // сложение строк

      {

        if ( strlen ( str ) + strlen ( s2.str ) < SZ )

          strcat ( str, s2.str );

        else

          cout << "\nПереполнение!";

      }

};

///////////////////////////////////////////////////////////

int main ( )

{

  String s1 ( "С Новым годом!  " ); // конструктор с одним параметром

  String s2 = "С новым счастьем!";  // аналогично, но в другой форме

String s3;                          // конструктор без параметров

 

  cout << "\ns1="; s1.display ( );  // показываем все строки

  cout << "\ns2="; s2.display ( );

  cout << "\ns3="; s3.display ( );

 

  s3 = s1;                          // присвоение

  cout << "\ns3="; s3.display ( );

 

  s3.concat ( s2 );                 // сложение

  cout << "\ns3="; s3.display ( );

  cout << endl;

 

  return 0;

}

Класс String содержит массив типа char. Может показаться, что наш заново определенный класс — это то же самое, что и определение строки: массив типа char. Но, поместив массив в класс, мы получили некоторую выгоду. Так как объ- екту может быть присвоено значение другого объекта того же класса, используя операцию =, то мы можем использовать выражения типа

S3 = s1;

как мы сделали в функции main (), для установки одного объекта класса String равным другому объекту. Мы можем также определить наши собственные мето- ды для работы с объектами класса String.

В программе STROBJ все строки имеют одинаковую длину: SZ символов (SZ установлено равным 80). В ней есть два конструктора. В первом начальный символ в str устанавливается равным '\0', чтобы длина строки была равной 0. Этот конструктор вызывается в строке

String s3;

Второй конструктор присваивает объекту класса String значение строковой константы. Он использует библиотечную функцию strcpy() для копирования строковой константы в переменную объекта. Конструктор вызывается в строке

String s1 ( "С Новым годом! " );

Альтернативный формат вызова этого конструктора, работающий с любым одноаргументным конструктором, будет таким

String s1 = "С Новым годом! ";

Какой бы формат вы ни использовали, этот конструктор эффективно преоб- разует строковый тип в объект класса String, то есть обычную строковую кон- станту в объект. Метод display() выводит строку объекта на экран.

Другой метод нашего класса String, concat(), объединяет один объект класса String с другим (складывает две строки). Первоначальный объект вызывает ме- тод, то есть к его строке будет добавлена строка объекта, переданного в качестве аргумента. Таким образом, строка функции main()

s3.concat ( s2 );

служит для прибавления строки s2 к уже существующей строке s3. Так как s2 инициализирована как «С новым счастьем!», а S3 было присвоено значение s1, «С Новым годом!», то в результате значением s3 будет «С Новым годом! С но- вым счастьем!»

Метод concat() использует библиотечную функцию языка C strcat() для выполнения объединения строк. Эта библиотечная функция присоединяет стро- ку второго аргумента к строке первого аргумента. Вывод программы будет таким:

s1=C Новым годом!

s2=C новым счастьем!

s3=         - сейчас строка пуста

s3=C Новым годом!      - аналог s1

s3=C Новым годом! С новым счастьем!            - после добавления s2

Если длина двух строк, объединенных методом concat(), превысит макси- мальную длину строки для объекта String, то объединение не будет выполнено, а пользователь получит сообщение об ошибке.

Мы рассмотрели простой строковый класс. Теперь мы рассмотрим более сложную версию того же класса.

 

26