Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

i++; // постфиксный

++i; // префиксный

Оба инкрементируют

i
: первая версия создает временную копию
i
, инкрементирует
i
и затем возвращает временное значение, а вторая инкрементирует
i
и затем возвращает его. C++ позволяет выполнять перегрузку операторов, что означает, что вы можете заставить свой собственный тип (класс или
enum
) вести себя так же, как и
int
.

Чтобы добиться нужного эффекта, перегрузите

operator++
и
operator--
. Пример 8.14 иллюстрирует, как перегружать префиксную и постфиксную версии.

Score& operator++ { // префиксный

 ++score_;

 return(*this);

}

const Score operator++(int) { // постфиксный

 Score tmp(*this);

 ++(*this);

 return(tmp);

}

Префикс выглядит так, как и следует ожидать, но компилятор различает эти две версии, и в объявление постфиксной версии включается параметр

int
. Он не имеет семантического применения — он всегда передается как ноль, так что его можно игнорировать.

После этого класс

Score
можно использовать как
int
.

Score player1(50);

player1++;

++player1; // score_ = 52

Вы, вероятно, заметили, что сигнатуры префиксной версии

operator++
возвращают ссылку на текущий класс. Именно так и следует делать (а не возвращать, к примеру,
void
), чтобы инкрементируемый или декрементируемый объект мог использоваться в других выражениях. Рассмотрим такую строку из примера.

(--player1)--;

Да, это странно, но она иллюстрирует этот момент. Если бы префиксный

operator--
не возвращал чего-то осмысленного, то это выражение не скомпилировалось бы. Еще один пример показывает вызов функции.

foo(--player1);

Функция

foo
ожидает аргумент типа
Score
, и для корректной компиляции именно это должно возвращаться из префиксного
operator--
.

Перегрузка операторов — это мощная возможность, которая позволяет для типов, определяемых пользователем, использовать те же операторы, что и для встроенных типов. Сторонники других языков, которые не поддерживают перегрузку операторов, утверждают, что эта возможность сбивает с толку и очень сложна, и, следует признать, может быть перегружено очень много операторов, соответствующих любому поведению. Но когда дело касается простого инкремента и декремента, хорошо иметь возможность изменить поведение класса так, как этого хочется.

Смотри также

Рецепт 8.14.

8.14. Перегрузка арифметических операторов и операторов присвоения для работы с классами

Проблема

Имеется класс, для которого имеют смысл некоторые из унарных или бинарных операторов С++, и требуется, чтобы пользователи класса могли использовать их при работе с объектами этого класса. Например, если есть класс с именем

Balance
, который содержит значение с плавающей точкой (например, баланс счета), будет удобно, если для объектов
Balance
можно было бы использовать некоторые стандартные операторы С++, как здесь.

Balance checking(50.0);

savings(100.0);

checking += 12.0;

Balance total = checking + savings;

Решение

Перегрузите операторы, которые требуется использовать как методы и отдельные функции, указав аргументы различных типов, для которых данный оператор имеет смысл, как в примере 8.15.

Пример 8.15. Перегрузка унарных и бинарных операторов

#include <iostream>

using namespace std;

class Balance {

 // These have to see private data

 friend const Balance operator+(const Balance& lhs, const Balance& rhs);

 friend const Balance operator+(double lhs, const Balance& rhs);

 friend const Balance operator+(const Balance& lhs, double rhs);

public:

 Balance : val_(0.0) {}

 Balance(double val) : val_(val) {}

 ~Balance {}

 // Унарные операторы

 Balance& operator+=(const Balance& other) {

val_ += other.val_;

return(*this);

 }

 Balance& operator+=(double other) {

val_ += other;

return(*this);

 }

 double getVal const {return(val_);}

private:

 double val_;

};

// Бинарные операторы

const Balance operator+(const Balance& lhs, const Balance& rhs) {

 Balance tmp(lhs.val_ + rhs.val_);

 return(tmp);

}

const Balance operator+(double lhs, const Balance& rhs) {

 Balance tmp(lhs + rhs.val_);

 return(tmp);

}

const Balance operator+(const Balance& lhs, double rhs) {

 Balance tmp(lhs.val_ + rhs);

 return(tmp);

}

int main {

 Balance checking(500.00);

 savings(23.91);

 checking += 50;

 Balance total = checking + savings;

 cout << "Платежный баланс: " << checking.getVal << '\n';

Поделиться:
Популярные книги

Идеальный мир для Лекаря 30

Сапфир Олег
30. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 30

Плеяда

Суконкин Алексей
Проза:
военная проза
русская классическая проза
5.00
рейтинг книги
Плеяда

Непристойное предложение. Книга 2

Кроу Лана
2. Предложение
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Непристойное предложение. Книга 2

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке

Невеста напрокат

Завгородняя Анна Александровна
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Невеста напрокат

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Ваше Сиятельство 5

Моури Эрли
5. Ваше Сиятельство
Фантастика:
городское фэнтези
аниме
5.00
рейтинг книги
Ваше Сиятельство 5

Имя нам Легион. Том 9

Дорничев Дмитрий
9. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 9

Последний Паладин. Том 2

Саваровский Роман
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 2

Жандарм 2

Семин Никита
2. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Жандарм 2

Антимаг его величества. Том II

Петров Максим Николаевич
2. Модификант
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Антимаг его величества. Том II

Возвышение Меркурия. Книга 3

Кронос Александр
3. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 3

Лолита

Набоков Владимир Владимирович
Проза:
классическая проза
современная проза
8.05
рейтинг книги
Лолита

Идеальный мир для Лекаря 15

Сапфир Олег
15. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 15