- •Введение в перегрузку операций
- •Операции, как функции
- •Использование перегруженных операций
- •Ограничения в перегрузке операций
- •Перегрузка операций через дружественные функции
- •Перегрузка операций через дружественные функции
- •Int main () {
- •I have 16 dollars.
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Дружественные функции могут быть определены внутри класса
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Перегрузка операций с операндами разных типов
- •Int m_dollars;
- •Int getDollars () {return m_dollars;}
- •Int main () {
- •Values (int min, int max) {
- •Int getMin () {return m_min;}
- •Int getMax () {return m_max;}
- •Int main () {
- •Int main () {
- •Int main () {
- •Перегрузка операций через обычные функции
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Перегрузка операций ввода и вывода
- •Void print () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int m_numerator;
- •Int m_denominator;
- •Void reduce () {
- •Void print () {
- •Перегрузка операций через методы классов
- •Int m_dollars;
- •Int getDollars () { return m_dollars; }
- •Int main () {
- •Int m_dollars;
- •Int getDollars () {return m_dollars;}
- •Int main (){
- •Не всё может быть перегружено через дружественные функции
- •Не всё может быть перегружено через методы класса
- •Int main (){
- •Какой способ перегрузки и когда следует использовать?
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •If (!isHappy)
- •Int main () {
- •If (!something)
- •Перегрузка операций сравнения
- •Int main () {
- •Int m_dollars;
- •Int main () {
- •Перегрузка операторов инкремента и декремента
- •Int m_number;
- •Int main () {
- •Перегрузка операций инкремента и декремента версии постфикс
- •Int m_number;
- •Int main () {
- •Перегрузка операции индексации []
- •Почему оператор индексации [] использует возврат по ссылке?
- •Использование оператора индексации с константными объектами класса
- •Int& operator[] (const int index);
- •Int main (){
- •IntArray array;
- •Проверка ошибок
- •Int m_array[10];
- •Int& operator [] (const int index);
- •Int& IntArray::operator[] (const int index) {
- •Указатели на объекты и перегруженный оператор []
- •Передаваемый аргумент не обязательно должен быть целым числом
- •Void operator [] (std::string index);
- •Void Something::operator [] (std::string index){
- •Int main () {
- •Перегрузка операции ()
- •Int main () {
- •Void operator() ();
- •Void Matrix::operator()() {
- •Int main() {
- •Перегрузка операций преобразования типов данных
- •Int m_dollars;
- •Int getDollars () { return m_dollars; }
- •Int main () {
Перегрузка операций преобразования типов данных
Как мы уже знаем о неявном преобразовании типов данных, C++ позволяет конвертировать значения из одного типа данных в другой. Например, преобразуем значение типа int в значение типа double:
int a = 7;
double b = a; // значение типа int неявно конвертируется в значение
//типа double
Язык C++ по умолчанию знает, как выполнять преобразования встроенных типов данных.
Однако он не знает, как выполнять конвертацию с пользовательскими типами данных (например, с классами). Именно здесь вступает в игру перегрузка операций преобразования типов данных. Рассмотрим следующий класс:
class Dollars {
private:
Int m_dollars;
public:
Dollars (int dollars=0) {
m_dollars = dollars;
}
Int getDollars () { return m_dollars; }
void setDollars (int dollars) { m_dollars = dollars; }
};
Класс Dollars содержит некое количество долларов в виде целого числа (переменная-член m_dollars) и предоставляет функции доступа для получения и установления значения m_dollars.
В нем также есть конструктор для конвертации значений типа int в тип Dollars (при создании объекта пользователь передает в качестве аргумента значение типа int, которое затем преобразуется в значение типа Dollars).
Если мы можем конвертировать int в Dollars, то логично было бы, если бы мы могли конвертировать и Dollars обратно в int, не так ли?
Иногда это может быть полезным.
В следующем примере мы используем метод getDollars() для конвертации значения типа Dollars в тип int для его последующего вывода через функцию printInt():
void printInt (int value) {
std::cout << value;
}
int main () {
Dollars dollars (9);
printInt (dollars.getDollars ()); // выведется 9
return 0;
}
Согласитесь, вызывать каждый раз метод getDollars() не очень удобно. Было бы проще перегрузить операцию преобразования значений типа Dollars в тип int.
Делается это следующим образом:
class Dollars {
private:
int m_dollars;
public:
Dollars (int dollars=0) {
m_dollars = dollars;
}
// Перегрузка операции преобразования значений типа Dollars в //значения типа int
operator int () {return m_dollars;}
int getDollars () {return m_dollars;}
void setDollars (int dollars) {m_dollars = dollars;}
};
Здесь есть две вещи, на которые следует обратить внимание:
В качестве функции перегрузки используется метод operator int().
Обратите внимание, между словом operator и типом, в который мы хотим выполнить конвертацию (в данном случае, тип int), находится пробел.
Функция перегрузки не имеет типа возврата. Язык C++ предполагает, что вы будете возвращать корректный тип.
Теперь функция printInt () вызывается проще:
Int main () {
Dollars dollars (9);
printInt(dollars); // выведется 9
return 0;
}
Сначала компилятор видит, что функция printInt () должна принимать целочисленный параметр (из определения printInt ()).
Затем он видит, что переменная dollars не является типа int.
Он смотрит, предоставили ли мы способ конвертации значения типа Dollars в тип int. Так как это у нас есть, то вызывается operator int (), который возвращает значение типа int, и это значение передается в printInt().
Теперь мы можем явно конвертировать объект класса Dollars в тип int:
Dollars dollars(9);
int d = static_cast<int>(dollars);
Вы можете перегружать операции преобразования любых типов данных, включая ваши собственные (пользовательские) типы данных!
Например, вот класс Cents, в котором осуществлена перегрузка операции преобразования значения типа Cents в значение типа Dollars:
class Cents {
private:
int m_cents;
public:
Cents (int cents=0) { m_cents = cents; }
// Выполняем конвертацию Cents в Dollars
operator Dollars () { return Dollars(m_cents / 100); }
};
Таким образом мы можем напрямую конвертировать центы в доллары:
#include <iostream>
class Dollars {
private:
int m_dollars;
public:
Dollars (int dollars = 0) { m_dollars = dollars;}
// Перегрузка операции преобразования значения типа Dollars в //значение типа int
operator int () {return m_dollars;}
int getDollars () {return m_dollars;}
void setDollars (int dollars) {m_dollars = dollars;}
};
class Cents {
private:
int m_cents;
public:
Cents (int cents=0) { m_cents = cents;}
// Выполняем конвертацию Cents в Dollars
operator Dollars () { return Dollars(m_cents / 100); }
};
void printDollars (Dollars dollars) {
std::cout << dollars; // dollars неявно конвертируется в int здесь
}
int main () {
Cents cents (700);
printDollars (cents); // cents неявно конвертируется в Dollars здесь
return 0;
}
Результат выполнения программы:
7
Всё логично: 700 центов = 7 долларов!
