- •Методология ооп
- •Инкапсуляция
- •Полиморфизм
- •Структура и класс.
- •Встроенная функция
- •Приватные или защитные члены класса
- •Доступ к приватным членам класса
- •Дружественные функции
- •Статические члены класса
- •Массив объекта
- •Деструкторы
- •Деструкторы и динамическое распределение памяти
- •Реализация конструктора копирования
- •Перегрузка операции
- •Реализация перегруженной операции
- •Левые функции
Перегрузка операции
Перегрузка операции – очень важное средство в объектно-ориентированном программировании, поскольку позволяет заставить стандартные операции, такие как арифметические, логические и т.д., работать с объектами собственных типов данных. Как и для стандартных операций, приоритет всех операций сохраняется и для перегруженных операций собственных типов данных.
Приоритет выполнения операций:
::
() [] {}
* /
+ -
=
> < >= <= ==
?:
Z=(a>b)?a:((a>=c)?b:((c<d)?d:a)))
С++ не позволяет перегружать новые операции, кроме стандартных. При этом следующие операции не могут быть перегружены.
1 - ::
2 - ?:
3 - . операция прямого доступа к членам класса
4 – sizeof
5 - * операция разыменования
Перегруженные операции могут быть либо методом класса, либо как обычные глобальные функции, однако следующие перегруженные операции могут быть только функциями-членами класса:
1 - = присваивание
2 – () операция вызова функции
3 – [] операция индексирования
4 - -> операция косвенного доступа к членам класса
Перегруженные операции определяются с помощью ключевого слова operator
<тип возврата> Operator <операция>(<список параметров>)
{тело функции}
Реализация перегруженной операции
Неполная перегрузка операции «>»
Class Box
{ public:
…
Bool operator > (Box aBox) const;
// остальная часть тела класса
};
] Box cigarBox (4.0,3.0,1.0);
Box matchbox (1.1,2.2,0.5);
If (cigarbox>matchbox)
Cout<<”The volume of cigar is bigger than matchbox \n“;
Else
Cout<<”cigarBox is smaller than matchbox \n”;
Указатель this всегда будет указывать на объект слева от перегруженной операции. Это значит, что через этот объект (cigarbox) вызывается перегруженная операция operator>, а второй объект, находящийся справа – предается в качестве аргумента в функцию operator>.
В целях оптимизации можно в качестве аргумента передавать не целый объект, а ссылку на объект:
Bool Box::operator > (Box &aBox) const;
{return this->Volume()>aBox.Volume();}
]
Box cigarBox (4.0,3.0,1.0);
Box matchbox (1.1,2.2,0.5);
If (cigarbox>matchbox)
Cout<<”The volume of cigar is bigger than matchbox \n“;
Else
Cout<<”cigarBox is smaller than matchbox \n”;
Double value=20.0;
If (cigar>Value)
Cout<<”The volume of cigar is bigger than”<<Value<<endl;
Else <<”Trololo”;
Вторая часть программы не заработает, потому, что не найдет перегрузку для переменной типа double. Все можно исправить, добавив перед телом программы необходимую перегрузку:
Bool Box::operator > (double &Value) const;
{return this->Volume()>Value;}
Третий вариант развития событий:
If (value>cigarbox)
Тролооло
Else Тралала
This в данном случае никуда не будет указывать.
Функция-член операции всегда представляет левый аргумент как указатель this. Поскольку, в данном случае левый аргумент имеет тип double, мы не можем это реализовать как функцию-член, поскольку в данном случае есть 2 варианта выбора: либо перегружать эту операцию как обычную глобальную функцию, либо как дружественную функцию. Но так, как нет необходимости к прямому доступу к приватным членам класса, то случай с дружественной функцией не нужен. Остается только создать глобальную функцию для перегруженной операции для третьего случая:
Bool operator > (double &Value, Box &aBox) const;
{return Value > aBox.Volume();}
Конечный код полной перегрузки операции >
Class Box
{ public:
Box(double lv=1.0,double hv=1.0,double bv=1.0)
{cout<<”Constructor called \n”;
L=lv; H=hv; W=bv;}
Double Volume(){return L*H*W;}
Bool operator > (Box &aBox) const;
{return this->Volume()>aBox.Volume();}
Bool operator > (double &Value) const;
{return this->Volume()>Value;}
~Box(){cout<<”destructor called\n”;}
Private:
Double L,H,W;
};
Bool operator > (double &Value, Box &aBox) const;
{return Value > aBox.Volume();}
Int main()
{Box smallB(4.0, 2.0, 1.0);
Box mediumB(10.0,4.0,2.0);
If (mediumB>smallB)
Cout<<”mediumB is bigger than smallB\n”;
Else
If (medium>50.0)
Cout<<”the volume of mediumB > then”<<50;
Else
Cout<<”the volume of mediumB isn’t bigger than 50”<<endl;
If(10.0>smallB) cout<<”the V of small is smaller than 10”<<endl;
Else cout<<”\n the V of smallB is bigger than 10”<<endl;
Return 0;
}
Перегрузка операции присваивания.