Эта статья является дополнением к статье «Перегрузка операторов в С++». В ней будет рассмотрена перегрузка операций =
(присваивание), ==
(равенство) и [ ]
(индексация). Думаю, новичкам будет полезно попрактиковаться и увидеть некоторые нюансы их перегрузки.
Поставим перед собой следующие задачи:
- создать класс, который будет содержать элементы:
int *numbers
— указатель на массив целых чисел иsizeOfArray
— размер этого массива; - перегрузить оператор
[]
так, чтобы мы могли изmain
-функции присваивать значение элементам массива класса. Например, написав выражениеObject[0] = 3
, значение3
запишется в ячейку с индексом0
массиваint *numbers
. Теперь нам не придется определять и вызывать метод, который бы выполнял эту операцию (к примеру:Object.setNumber(0,3);
где0
– индекс массива а3
– то что нужно записать); - перегрузить оператор
==
чтобы можно было сравнить массивыint *numbers
двух разных объектов класса; - перегрузить оператор
=
так, чтобы записав выражениеObject = Object2
массивint *numbers
объектаObject
стал идентичными массиву объектаObject2
и по количеству ячеек массива и по значениям, которые хранят ячейки массива.
Вот решение:
#include <iostream> using namespace std; class MyArray { int *numbers; int sizeOfArray; public: MyArray() //конструктор без параметров { sizeOfArray = 0; numbers = 0; } //----------------------------------------------- MyArray(int size) //конструктор с параметрами { sizeOfArray = size; numbers = new int [sizeOfArray]; for(int i = 0; i < sizeOfArray; i++) { numbers[i] = 0; } } //----------------------------------------------- ~MyArray() //деструктор { delete [] numbers; } //----------------------------------------------- void showData() //вывод данных массива на экран { for(int i = 0; i < sizeOfArray; i++) { cout << numbers[i] << " | "; } cout << endl << endl; } //----------------------------------------------- // на место вызова [] вернется по ссылке сам объект int &operator[](int j) //перегрузка [] { return numbers[j]; } //----------------------------------------------- MyArray& operator=( MyArray &arrInt2 ) //перегрузка оператора присваивания { delete [] numbers; sizeOfArray = arrInt2.sizeOfArray; numbers = new int [sizeOfArray]; for (int i = 0; i < sizeOfArray; i++) { numbers[i] = arrInt2.numbers[i]; } return *this; } //----------------------------------------------- friend bool operator ==( MyArray &arrInt, MyArray &arrInt2 ); //перегрузка == }; bool operator == ( MyArray &arrInt, MyArray &arrInt2 ) { if(arrInt.sizeOfArray != arrInt2.sizeOfArray) //сравниваем размеры массивов объектов { cout << "В массивах разное количество элементов\n"; return 0; } else //проверяем равны ли данныев в ячейках массивов { for (int i = 0; i < arrInt.sizeOfArray; i++) { if(arrInt.numbers[i] != arrInt2.numbers[i]) { cout << "Значения массивов не равны\n"; return 0; } } } return 1; } int main() { setlocale(LC_ALL, "rus"); MyArray ArrayInt(5); //создаем объект класса и записываем в него данные ArrayInt[0] = 1; //перегруженный [] ArrayInt[1] = 2; ArrayInt[2] = 3; ArrayInt[3] = 4; ArrayInt[4] = 5; cout << "Массив ArrayInt: "; ArrayInt.showData(); //вывод данных массива на экран MyArray ArrayInt2(5); //создаем второй объект класса ArrayInt2[0] = 11; //перегруженный [] ArrayInt2[1] = 22; ArrayInt2[2] = 33; ArrayInt2[3] = 44; ArrayInt2[4] = 55; cout << "Массив ArrayInt2: "; ArrayInt2.showData(); //вывод данных массива на экран if(ArrayInt == ArrayInt2){ //сравнение двух объектов класса (перегруженный ==) cout << "Массив ArrayInt равен массиву ArrayInt2\n"; } else { ArrayInt = ArrayInt2; } cout << "Массив ArrayInt после копирования: "; ArrayInt.showData(); MyArray ArrayInt3(10); // третий объект класса с массивом из 10 элементов cout << "Массив ArrayInt3: "; ArrayInt3.showData(); ArrayInt3 = ArrayInt; // копируем массив из ArrayInt в ArrayInt3 cout << "Массив ArrayInt3 после копирования: \n"; ArrayInt3.showData(); return 0; }
И так — определяем класс MyArray
. В строках 9 — 28 определены конструкторы и деструктор. Тот конструктор, который принимает параметр, будет сразу, при создании объекта класса, задавать размер sizeOfArray
массива numbers
. В строках 39-43 перегружаем оператор индексирования []
. На место вызова []
вернется по ссылке сам объект и в ячейку его массива numbers
под номером j
мы сможем записать целое число.
Ниже в строках 46 — 59 перегружаем =
(присваивание). Он будет копировать массив одного объекта класса MyArray
в массив другого объекта класса. Чтобы это произошло, достаточно будет написать следующее выражение Object = Object2. При использовании перегруженного =
, вызывается функция MyArray& operator=( MyArray &arrInt2 )
определенная в классе. Первый параметр (объект класса который прописан слева от знака =
) в нее передается неявным образом по указателю this, а тот, что в скобках – это тот объект который указан справа от =
. Далее выполняется код тела этой функции – определение нового размера массива первого объекта и корректное копирование в него данных элементов массива второго объекта. Возвращает функция указатель на объект return *this;
(указатель на самого себя, только уже с внесенными изменениями).
Перегрузка ==
(равенства) у нас определена в строках 64 — 83. А в теле класса прописан ее прототип, как дружественной функции класса. Так как оператор ==
используется для сравнения объектов, то функция его перегрузки будет возвращать значение типа bool
. Она вернет 1
, если массивы объектов равны и по размеру и, по значениям в ячейках массивов. А если нет – вернет 0
и соответствующее сообщение о том, что не совпадает.
Ну а в main()
мы просто применяем все перегруженные операторы так, как нам надо для работы.
Результат работы программы:
Массив ArrayInt: 1 | 2 | 3 | 4 | 5 |
Массив ArrayInt2: 11 | 22 | 33 | 44 | 55 |
Значения массивов не равны
Массив ArrayInt после копирования: 11 | 22 | 33 | 44 | 55 |
Массив ArrayInt3: 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Массив ArrayInt3 после копирования:
11 | 22 | 33 | 44 | 55 |
Комментарии
Данил Токарев
Да уж. Шел по порядку и застопорился на этой статье -.- Вот нафига нужны эти ‘&‘? Почему перегруженный оператор должен вернуть именно ссылку? (я про «[ ]» и «=«)
npavelFax
Работа через интернет официальное трудоустройство.
Georgy Petrov
JIeo
Программа поломается если причсвоить самого себя…Тут ляп такчто думайте лучше…где эта ошибка и как ее поличить…
JIeo
Странно тут ляп большой ,если попробывыть присвоить самого себя то все паломается…
В операторе присваивания
if(this!=& arrInt2){
все что написано там…
}