Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_Посібник (1).doc
Скачиваний:
8
Добавлен:
01.05.2019
Размер:
544.77 Кб
Скачать

§8. Перезавантаження операцій

У C++ існує можливість перезавантаження стандартних операцій:

+

-

/

*

%

^

&

|

~

!

=

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

!=

>=

<=

&&

||

++

--

->*

,

->

[]

()

==, new,new[],delete, delete[].

Розрізняють унарні (один аргумент) або бінарні (два аргументи) оператори. Операції, які не можна перезавантажувати:

  1. . (вибір члена)

  2. .* (вибір члена через вказівник на член)

  3. :: (дозвіл області видимості)

  4. ? : # ## (умовний оператор)

Ім'я операторної функції починається з ключового слова 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).

Об’ява функції-члена гарантує три речі:

  1. функція має право доступу до закритих членів;

  2. функція знаходиться в області видимості класу;

  3. функція повинна викликатися для об’єкта класа.

Функція-член, яка визначена як 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();

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]