- •Введение в перегрузку операций
- •Операции, как функции
- •Использование перегруженных операций
- •Ограничения в перегрузке операций
- •Перегрузка операций через дружественные функции
- •Перегрузка операций через дружественные функции
- •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 () {
Почему оператор индексации [] использует возврат по ссылке?
Рассмотрим детально, как обрабатывается операция array [4] = 5. Поскольку приоритет операции индексации выше приоритета операции присваивания, то сначала выполняется часть array [4].
array [4] приводит к вызову функции перегрузки операции [], которая возвратит array.m_array [4].
Поскольку операция [] использует возврат по ссылке, то она возвращает фактический элемент array.m_array [4].
Наше частично обработанное выражение становится array.m_array[4] = 5, что является прямой операцией присваивания значения элементу массива.
Мы уже хорошо знаем, что любое значение, которое находится слева от операции присваивания, должно быть l-value (переменной с адресом в памяти).
Поскольку результат выполнения операции [] может использоваться в левой части операции присваивания (например, array[4] = 5), то возвращаемое значение операции [] должно быть l-value.
Ссылки же всегда являются l-values, так как их можно использовать только с переменными, которые имеют адреса памяти.
Поэтому, используя возврат по ссылке, компилятор останется доволен, что возвращается l-value, и никаких проблем не будет.
Рассмотрим, что произойдет, если операция [] будет использовать возврат по значению вместо возврата по ссылке. array[4] приведет к вызову функции перегрузки операции [], которая будет возвращать значение элемента array.m_array[4] (не индекс, а значение по указанному индексу).
Например, если значением m_array[4] является 7, то выполнение операции [] приведет к возврату значения 7. array[4] = 5 будет обрабатываться как 7 = 5, что является бессмысленным!
Если вы попытаетесь это сделать, то компилятор выдаст следующую ошибку:
C:VCProjectsTest.cpp(386): error C2106: '=' : left operand must be l-value
Использование оператора индексации с константными объектами класса
В вышеприведенном примере метод operator[]() не является константным, и мы можем использовать этот метод для изменения данных неконстантных объектов.
Однако, что произойдет, если наш объект класса IntArray будет const?
В этом случае мы не сможем вызывать не константный operator[](), так как он изменяет значения объекта (ранее было детально о классах и const).
Хорошей новостью является то, что мы можем определить отдельно неконстантную и константную версии operator[]().
Неконстантная версия будет использоваться с неконстантными объектами, а версия const — с объектами const:
#include <iostream>
class IntArray {
private:
int m_array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // указываем начальные //значения
public:
Int& operator[] (const int index);
const int& operator[] (const int index) const;
};
int& IntArray::operator[] (const int index) // для неконстантных //объектов: может использоваться как для присваивания значений //элементам, так и для их просмотра
{ return m_array[index];}
const int& IntArray::operator[] (const int index) const // для //константных объектов: используется только для просмотра //(вывода) элементов массива
{ return m_array[index];}
