Главная страница

Курс ООП в С презентация. ООП в с++(полный курс). Объекты и классы


Скачать 1.76 Mb.
НазваниеОбъекты и классы
АнкорКурс ООП в С презентация
Дата21.02.2022
Размер1.76 Mb.
Формат файлаppt
Имя файлаООП в с++(полный курс).ppt
ТипДокументы
#368655
страница8 из 26
1   ...   4   5   6   7   8   9   10   11   ...   26

Перегрузка операций


C++ позволяет переопределить действие большинства операций так, чтобы при использовании с объектами конкретного класса они выполняли заданные функции. Эта дает возможность использовать собственные типы данных точно так же, как стандартные. Обозначения собственных операций вводить нельзя. Можно перегружать любые операции, существующие в C++, за исключением следующих:
Перегрузка операций осуществляется с помощью методов специального вида (функций-операций) и подчиняется следующим правилам:
    при перегрузке операций сохраняются количество аргументов, приоритеты операций и правила ассоциации (справа налево или слева направо), используемые в стандартных типах данных;
    для стандартных типов данных переопределять операции нельзя;
    функции-операции не могут иметь аргументов по умолчанию;
    функции-операции наследуются (за исключением =);
    функции-операции не могут определяться как static.


.*


?:


::


#


##


sizeof

Перегрузка операций


Функция-операция должна быть либо методом класса, либо дружественной функцией класса, либо обычной функцией. В двух последних случаях функция должна принимать хотя бы один аргумент, имеющий тип класса, указателя или ссылки на класс.
Функция-операция содержит ключевое слово operator, за которым следует знак переопределяемой операции:
тип operator операция(список параметров){ тело функции }


Перегрузка унарных операций


Унарная (т.е. имеющая) функция-операция, определяемая внутри класса, должна быть пред­ставлена с помощью нестатического метода без параметров, при этом операндом является вызвавший ее объект.
class person
{
public:

person& operator++();
};
person& person::operator++()
{
++weight; return *this;
}
person x;
++x;
cout << x.get_weight();
Запись ++x; интерпретируется компилятором как вызов компонентной функции x.++().


Если функция определяется вне класса, она должна иметь один параметр типа класса.
class person
{

friend person& operator--(person &rhs);
};
person& operator--(person &rhs)
{
--rhs.weight; return rhs;
}
person x;
--X;
cout << x.get_age();
В этом случае запись --x; интерпретируется компилятором как вызов глобальной функции --(x).


Операции постфиксного инкремента и декремента должны иметь фиктивный параметр типа int. Он используется только для того, чтобы отличить их от префиксной формы.
class person
{

person& operator ++(int);
};
Если не описывать функцию внутри класса как дружественную, нужно учитывать доступность изменяемых полей. В данном случае поле weight недоступно извне, так как описано со спецификатором private, поэтому для его изменения требуется использование метода-модификатора set_weight(). В таком случае можно перегрузить операцию инкремента с помощью обычной функции, описанной вне класса:
person& operator ++(person& p, int)
{
double w = p.get_weight(); w++; p.set_weight(w);
return p;
}


Перегрузка бинарных операций


Бинарная функция-операция, определяемая внутри класса, должна быть представлена с помощью нестатического метода с параметрами, при этом вызвавший ее объект считается первым операндом:
class person
{

bool operator<(person& rhs) const;
friend bool operator>(const person& p1, const person& p2);
};
bool person::operator<(person& rhs) const
{
return (weight < rhs.weight);
}


Запись X Если функция определяется вне класса, она должна иметь два параметра типа класса.
bool operator>(const person& p1, const person& p2)
{
return (p1.weight > p2.weight);
}
Запись X>Y, где X и Y объекты класса person будет интерпретироваться компилятором как вызов глобальной функции >(X,Y).


Перегрузка операции присваивания


Операция присваивания определена в любом классе по умолчанию как поэлементное копирование. Эта операция вызывается каждый раз, когда одному существующему объекту присваивается значение другого. Если класс содержит поля, память под которые выделяется динамически, необходимо определить собственную операцию присваивания. Чтобы сохранить семантику присваивания, операция-функция должна возвращать ссылку на объект, для которого она вызвана, и принимать в качестве параметра единственный аргумент – ссылку на присваиваемый объект.
person& person::operator=(person& rhs)
{
//проверка на самоприсваивание:
if (&rhs == this) return *this;
name = new char[strlen(rhs.name)+1];
strcpy(name, rhs.name);
year = rhs.year;
weight = rhs.weight;
return *this;
}


Возврат функцией ссылки на объект делает возможной цепочку операций присваивания:
person А("Vovan", 1960, 120), В, С;
С = В = А;
Операцию присваивания можно определять только как метод класса. Она не наследуется.


Перегрузка операции вызова функции


Класс, в котором определена операция вызова функции, называется функциональным. От такого класса не требуется наличия других полей и методов. Объект такого класса называется объект-функция.
class greater
{
public:
int operator()(int a, int b)
{
return a > b;
}
};
void main()
{
greater x;
cout << х(1, 5); // Результат - 0
cout << greater()(5, 1); // Результат – 1
}


Поскольку в классе greater определена операция вызова функции с двумя параметрами, выражение х(1,5) является допустимым и может быть записать в виде х.operator(1,5). Как видно из примера, объект функционального класса используется так, как если бы он был функцией.
Во втором операторе вывода выражение greater() используется для вызова конструктора по умолчанию класса greater. Результатом выполнения этого выражения является объект класса greater. Далее, как и в предыдущем случае, для этого объекта вызывается функция с двумя аргументами, записанными в круглых скобках.
Операцию () (а также операцию []) можно определять только как метод класса. Можно определить перегруженные операции вызова функции с различным количеством аргументов.


Идентичность объектов  

1   ...   4   5   6   7   8   9   10   11   ...   26


написать администратору сайта