Опубликован: 26.06.2003 | Уровень: для всех | Доступ: платный
Лекция 13:

Дополнительные возможности классов

< Лекция 12 || Лекция 13: 12 || Лекция 14 >
Аннотация: Рассматриваются дополнительные возможности при определении классов, включая переопределение операций, определение методов inline и задание собственных преобразований типа.

Переопределение операций

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

Определим две операции в классе String – сравнение на меньше и сложение:

class String
{
public:
     . . .
  String operator+(const String& s) const;
  bool operator<(const String& s) const;
};

Признаком того, что переопределяется операция, служит ключевое слово operator, после которого стоит знак операции . В остальном операция мало чем отличается от обычного метода класса. Теперь в программе можно записать:

String s1, s2;
. . .
s1 + s2

Объект s1 выполнит метод operator с объектом s2 в качестве аргумента.

Результатом операции сложения является объект типа String. Никакой из аргументов операции не изменяется. Описатель const при описании аргумента говорит о том, что s2 не может измениться при выполнении сложения, а описатель const в конце определения операции говорит то же самое об объекте, выполняющем сложение.

Реализация может выглядеть следующим образом:

String
String::operator+(const String& s) const
{
  String result;
  result.length = length + s.length;
  result.str = new char[result.length + 1];
  strcpy(result.str, str);
  strcat(result.str, s.str);
  return result; 
}

При сравнении на меньше мы будем сравнивать строки в лексикографической последовательности. Проще говоря, меньше та строка, которая должна стоять раньше по алфавиту:

bool
String::operator<(const String& s) const
{
  char* cp1 = str;
  char* cp2 = s.str;
  while (true) {
    if (*cp1 < *cp2)
      return true;
    else if (*cp1 > *cp2)
      return false;
    else {
      cp1++;
      cp2++;  
      if (*cp2 == 0)        // конец строки
        return false;
      else if (*cp1 == 0)   // конец строки  
        return true;
    }
  }
}

Как определять операции

Если для класса определяют операции, то обычно определяют достаточно полный их набор, так, чтобы объекты этого класса могли участвовать в полноценных выражениях.

Прежде всего, определим операцию присваивания. Операция присваивания в качестве аргумента использует объект того же класса и копирует значение этого объекта. Однако, в отличие от копирующего конструктора, у объекта уже имеется какое-то свое значение, и его нужно аккуратно уничтожить.

class String
{
public:
// объявление операции присваивания
String& operator=(const String& s);
};
// Реализация присваивания
String&
String::operator=(const String& s)
{
     if (this == &s)
          return *this;
     if (str != 0) {
          delete [] str;
     }
     length = s.length;
     str = new char[length + 1];
     if (str == 0) {
          // обработка ошибок
     }
     strcpy(str, s.str);
     return *this;
}

Обратим внимание на несколько важных особенностей операции присваивания. Во-первых, в качестве результата операции присваивания объект возвращает ссылку на самого себя. Это дает возможность использовать строки в выражениях типа:

s1 = s2 = s3;

Во-вторых, в начале операции проверяется, не равен ли аргумент самому объекту. Таким образом, присваивание s1 = s1 выполняется правильно и быстро.

В-третьих, перед тем как скопировать новое значение, операция присваивания освобождает память, занимаемую старым значением.

Аналогично операции присваивания можно определить операцию   +=.

Набор операций, позволяющий задействовать класс String в различных выражениях, представлен ниже:

class String
{
public:
  String();
  String(const String& s);
  String(const char*);
  String& operator=(const String& s);
  String& operator+=(const String& s);
  bool operator==(const String& s) const;
  bool operator!=(const String& s) const;
  bool operator<(const String& s) const;
  bool operator>(const String& s) const;
  bool operator<=(const String& s) const;
  bool operator>=(const String& s) const;
  String operator+(const String& s) const;
};
< Лекция 12 || Лекция 13: 12 || Лекция 14 >
Андрей Одегов
Андрей Одегов
Язык программирования C++
Елена Шумова
Елена Шумова

Здравствуйте! Я у Вас прошла курс Язык программировая Си++.

Заказала сертификат. Хочу изменить способ оплаты. Как это сделать?

Сергей Пантелеев
Сергей Пантелеев
Россия, Москва
Ахмет Арчаков
Ахмет Арчаков
Россия, Магас