- •Об’єкто-орієнтоване
- •Методичні рекомендації та модульні завдання
- •§1. Об’єкт. Структура. Клас.
- •§2. Управління доступом до членів класу
- •§3. Перезавантаження функцій
- •§4. Шаблони функцій
- •§5. Конструктори
- •§6. Статичні члени класу
- •§7. Деструктори
- •§8. Перезавантаження операцій
- •§9. Друзі класу
- •§10. Бінарні й унарні операції
- •§11. Створення класів з підкласами. Агрегація
- •Файл реалізації “Stack.Cpp”
- •§12. Успадкування
- •§13. Ієрархія успадкування класів
- •Модуль 1 (20 балів)
- •Лабораторна робота №1 (6 балів)
- •Тема: Структури. Зовнішні функції і функції-члени структури.
- •Завдання
- •Варіанти завдань
- •Лабораторна робота №2 (6 балів) Тема: Перезавантаження операцій і функцій Завдання
- •Варіанти завдань
- •Лабораторна робота №3 (8 балів) Тема: Структури та класи Завдання
- •Варіанти завдань
- •Варіанти завдань
- •Визначити функції:
- •Визначити функції:
- •Визначити функції:
- •Визначити функції:
- •Визначити функції:
- •Варіанти завдань
- •Лабораторна робота №6 (8 балів) Тема: Абстрактні класи Завдання
- •Варіанти завдань
- •Модуль контроль (15 балів) Теоретичні питання
- •Теоретичні питання
- •Модуль контроль підсумковий (30 балів)
- •Тематика задач
- •Теоретичні питання
- •Розподіл балів і годин
- •Список літератури
- •Навчальне видання
- •Методичні рекомендації та модульні завдання
- •58012, Чернівці, вул. Коцюбинського, 2
§8. Перезавантаження операцій
У C++ існує можливість перезавантаження стандартних операцій:
+ |
- |
/ |
* |
% |
^ |
& |
| |
~ |
! |
= |
< |
> |
+= |
-= |
*= |
/= |
%= |
^= |
&= |
|= |
<< |
>> |
>>= |
<<= |
|
!= |
>= |
<= |
&& |
|| |
++ |
-- |
->* |
, |
-> |
[] |
() |
|
==, new,new[],delete, delete[].
Розрізняють унарні (один аргумент) або бінарні (два аргументи) оператори. Операції, які не можна перезавантажувати:
. (вибір члена)
.* (вибір члена через вказівник на член)
:: (дозвіл області видимості)
? : # ## (умовний оператор)
Ім'я операторної функції починається з ключового слова operator і символа @, де @ – одна із вище наведених операцій.
Приклад 11:
class Complex{
double re,im;// дійсна та уявна частина відповідно
public:
Complex(double r, double i): re(r),in(i){}//конструктор Complex
Complex operator+(Complex&);//перезавантаження //оператора +
Complex operator*(Complex&);//перезавантаження //оператора *
};
Complex Complex::operator+(complex X){
return Complex(this->re+X.re,this->im+X.im);
}
Complex Complex::operator*(complex X){
return Complex(re*X.re-im*X.im, re*X.im+im*X.re);}
Операторна функція з'являється і може бути викликана, як будь-яка інша функція. Використання операторної функції як оператора є просто скороченою формою її явного виклику.
Наприклад:
void f(complex a, complex b) {
complex c=a+b; // скорочена форма
complex d=a.operator+(b); //явний виклик
}
Обмеження при перезавантаженні операцій:
1. Не можна перезавантажувати операції для некласових типів. Звідси випливає дві можливості: щоб операція була членом якогось класу, створеного користувачем або, щоб принаймні один з операндів цієї операції був класового типу.
2. При перезавантаженні не можна змінювати асоціативність, кількість операндів.
3. Обмежень на тип, що повертає перезавантажений оператор, немає.
§9. Друзі класу
Часто виникає необхідність в написанні функцій, які мають доступ до приватних секцій декількох класів, однак членом двох класів функція бути не може. Тому в С++ передбачено засіб мови, що надає функції право доступу до закритої частини класу. Функція-не-член, що одержала право доступу до закритої частини класу, називається другом класу (friend).
Об’ява функції-члена гарантує три речі:
функція має право доступу до закритих членів;
функція знаходиться в області видимості класу;
функція повинна викликатися для об’єкта класа.
Функція-член, яка визначена як static, володіє першими двома властивостями. Функція–член, визначена як friend, володіє першою властивістю.
Функція-друг – це звичайна функція, вона не має ніяких особливостей, крім права доступу до закритої частини класу. Зокрема, friend- функція не має вказівника this, оскільки вона не є повноправним членом-функцією. Ключове слово friend задається в прототипі функції перед її іменем і типом, що повертається. Опис дружньої функції може розташовуватися в закритій, чи у відкритій частині опису класу, де саме, значення не має. При написанні тіла дружньої функції оператор прив’язки не пишеться, тому що функція не є членом класу.
Наприклад, перезавантажимо оператор, який множить Matrix(матрицю) на Vector (вектор). Оскільки класи Matrix та Vector приховують свої елементи, об’явлені в секції private, доступ до цих елементів можна відкрити для інших функцій, об’явивши їх як friend.
Приклад 12:
#include "stdafx.h"
class Matrix;//попередня об'ява класу Matrix. Всі функції члени та дані //будуть описані пізніше. В класі Vector //використовується цей клас
class Vector{ //клас вектор
float v[4]; //масив, який містить координати вектора
public:
Vector(){//конструктор, який викликає інший для //ініціалізації даних
Vector(1,1,1,1);
}
Vector(float x1, float x2, float x3, float x4){//конструктор
v[0] = x1;v[1] = x2;v[2] = x3;v[3] = x4;
}
printVector () {
printf("%f,%f,%f,%f\n",v[0],v[1],v[2],v[3]);// член-функція } //( друк координат вектора)
Vector& operator = (Vector& X);//перезавантаження оператора =
//добуток матриці на вектор (дружній оператор )
friend Vector operator* (const Matrix&, const Vector&);
};
class Matrix{// клас Matrix
Vector v[4];//масив, який містить вектори
public:
Matrix() {//конструктор за замовчуванням);
// ініціалізація масиву векторів
for (int i = 0; i<4;i++) v[i] = Vector(1,1,1,1
}
Matrix(Vector x1, Vector x2, Vector x3, Vector x4){// конструктор, // який приймає аргументи – вектори х1, х2, х3,х4 для утворення //масиву
v[0] = x1;v[1] = x2;v[2] = x3;v[3] = x4;
}
printMatrix () { v[0].printVector(); //друк матриці
v[1].printVector();
v[2].printVector();
v[3].printVector(); }
friend Vector operator* (const Matrix&, const Vector&);
//дружній оператор
};
Vector& Vector::operator = (Vector& X){
v[0] = X.v[0];
v[1] = X.v[1];
v[2] = X.v[2];
v[3] = X.v[3];
return *this;
}
Vector operator* (const Matrix& m, const Vector& v)
{
Vector r;
for(int i=0;i<4;i++){
r.v[i] = 0;
for(int j=0;j<4;j++) r.v[i] += m.v[i].v[j]*v.v[j];
}
return r;
}
void main(){
Vector v(1,2,3,4), r; //створення векторів (конструктор з
//параметрами і конструктор за замовчуванням)
Matrix m;//створення матриці (конструктор за замовчуванням)
printf("Matrix m:\n");
m.printMatrix();
printf("Vector v:\n");
v.printVector();
r = m*v; //виклик дружної функції operator *, яка має доступ до //прихованих членів даних класу Vector і класу Matrix.
printf("Vector r:\n");
r.printVector();
}