C++: переопределяем префиксный, постфиксный, унарный и бинарный операторы
Забавно, 2 дня подряд всплывала эта тема - разница в переопределениях унарного и бинарного оператора в С++, пожалуй, сделаю пример для простейшего класса комплексных чисел. Оператор бинарного "+" будет переопределён так, что мы сможем складывать комплексные числа в естественном виде c=a+b
, а унарный "+" перед числом пусть меняет знак его мнимой части.
Насчёт переопределения префиксных и постфиксных операций в C++, кстати, тоже есть заморочки, так что добавим реализацию и префиксного, и постфиксного "++" для увеличения на 1 величины действительной части:
#include <stdio.h> class C { //C - имя класса комплексных чисел float re,im; //свойства для хранения действительной и мнимой частей public: C (float re=0, float im=0) { this->re=re; this->im=im; } //конструктор C operator + (C &); //переопределяем БИНАРНЫЙ "+" для сложения комплексных чисел C& operator + (void); //переопределяем УНАРНЫЙ префиксный "+" для смены знака мнимой части C& operator ++ (void); //переопределяем префискный ++ C operator ++ (int); //переопределяем постфискный ++ void show (void); //метод для вывода числа в консоль }; C C::operator + (C &c2) { //реализация БИНАРНОГО "+" - сложения чисел C sum = C (this->re+c2.re,this->im+c2.im); return sum; } C& C::operator + (void) { //реализация УНАРНОГО "+" -смены знака у мнимой части im=-im; return *this; } C& C::operator ++ (void) { //переопределяем префиксный ++ ++re; return *this; } C C::operator ++ (int) { //переопределяем постфиксный ++ - нужен параметр int C z(this->re,this->im); ++re; return z; } void C::show(void) { //вывод числа - не печатаем лишний "-" перед мнимой частью if (im<0) printf ("\n%.2f%.2fi",re,im); else printf ("\n%.2f+%.2fi",re,im); } int main (void) { C c1(1,-1); C c2(2,2); C c3=c1+c2; //сложили 2 комплексных числа printf ("\n\nПервое число с1"); c1.show(); printf ("\nВторое число с2"); c2.show(); printf ("\nСумма с3=с1+с2"); c3.show(); c2=+c2; //сменили знак у мнимой части printf ("\nСмена знака мнимой части числа с2"); c2.show(); printf ("\nВыполнили c0=c1++"); C c0=c1++; printf ("\nПосле этого c0"); c0.show(); printf ("\nПосле этого c1"); c1.show(); printf ("\nВыполнили c0=++c2"); c0=++c2; printf ("\nПосле этого c0"); c0.show(); printf ("\nПосле этого c2"); c2.show(); return 0; }
Если сказать совсем грубо, бинарный "+" порождает новый объект класса C
- число, являющееся результатом сложения. При выполнении сложения вида c=a+b;
для функции оператора должны быть доступны 2 объекта - объект a
через предопределённый указатель this
, объект b
через параметр (C &c2
в листинге), а в качестве c
возвращается созданный функцией объект sum
.
С унарным оператором всё проще - достаточно изменить нужное свойство текущего объекта, а новый не порождается.
Обратите также внимание, что префиксный оператор ++ просто изменит состояние объекта, а постфиксный должен создать временный объект (копию исходного) и вернуть его, при этом всё равно увеличив состояние нужного свойства исходного объекта.
Вывод этой программы:
Первое число с1 1.00-1.00i Второе число с2 2.00+2.00i Сумма с3=с1+с2 3.00+1.00i Смена знака мнимой части числа с2 2.00-2.00i Выполнили c0=c1++ После этого c0 1.00-1.00i После этого c1 2.00-1.00i Выполнили c0=++c2 После этого c0 3.00-2.00i После этого c2 3.00-2.00i
16.06.2013, 21:56 [12334 просмотра]