Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
С++ - ООП.doc
Скачиваний:
11
Добавлен:
21.09.2019
Размер:
399.87 Кб
Скачать

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

В языке С++ возможна перегрузка функций-элементов, конструкторов и операций.

Функции-элементы класса могут быть перегружены; две или несколько функций могут иметь одно и то же имя, при условии, что списки их аргументов не совпадают. Компилятор следит за тем, чтобы вызывалась нужная функция, проверяя соответствие аргументов. Довольно обычной является перегрузка конструкторов.

Конструкторы играют специфическую роль в языке С++. Перегрузка конструкторов класса осуществляется просто объявлением конструкторов с различным набором параметров.

Пример

#include <iostream.h>

#include <stdio.h>

#include <time.h>

class timer {

int seconds;

public:

timer(void) {seconds=5;} // конструктор по умолчанию

timer(char *t) { seconds=atoi(t);} // время задается строкой

timer(int t) {seconds=t;} // Задание секунд целым числом

timer (int min, int sec) { seconds=60*min+sec;} // задание минутами и секундами

void run(void);

};

void timer::run(void)

{

clock_t t1,t2;

t1=t2=clock()/CLK_TCK;

while(seconds) {

if (t1/CLK_TCK+1<=(t2=clock())/CLK_tck)

{

seconds--;

t1=t2;

}

}

сout<<”\a”; // сигнал

}

void main(void)

{

timer a(10), b(“20”), c(1,10),d;

сout<<”Подождите 10 секунд…\n”;

a.run(); // 10 секунд

сout<<”Подождите 20 секунд…\n”;

b.run(); // 20 секунд

сout<<”Подождите 1 минуту 10 секунд…\n”;

с.run(); // 1 минута 10 секунд

сout<<”Подождите 5 секунд…\n”;

d.run(); // 5 секунд

}

Язык С++ позволяет определять и применять к вашему классу обозначения операций. Эта особенность, называемая перегрузкой операций, дает классу возможность вести себя подобно встроенному типу данных. Можно перегружать для классов любые из следующих операций

+

-

*

.

%

^

&

|

!

=

<

>

+=

-=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

= =

!=

<=

>=

&&

||

++

--

[]

Чтобы перегрузить операцию, нужно определить, что эта значит относительно класса, к которому она будет применяться. Для этого создается специальная функция-операция (operator function), которая определяет действие этой операции.

Основная форма функции-операции, являющейся функцией-членом класса

Тип имя-класса::operator #(список аргументов)

{

// операторы, определяющие действие

}

тип – тип возвращаемого значения;

# - конкретный знак операции.

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

Пример. Перегрузка операций + и = относительно класса vector, который определяет трехмерный вектор в эвклидовом пространстве. Операция сложения векторов выполняется как сложение соответствующих координат

#include <iostream.h>

class vector {

int x,y,z; // координаты

public:

vector operator +(vector t);

vector operator =(vector t);

void show(void);

void assign(int mx, int my, int mz);

};

// перегрузка операции +

vector vector::operator + (vector t)

{

vector temp;

temp.x=x+t.x;

temp.y=y+t.y;

temp.z=z+t.z;

return temp;

}

// перегрузка операции =

vector vector::operator = (vector t)

{

vector temp;

x=t.x;

y=t.y;

z=t.z;

return *this;

}

void vector::show(void)

{

cout<<x<<” “<<y<<” “<<z<<endl;

}

void vector::assign(int mx, int my, int mz)

{

x=mx; y=my; z=mz;

}

void main(void)

{

vector a,b,c;

a.assign(1,2,3);

b.assign(4,5,6);

a.show();

b.show();

c=a+b; // использование перегруженной операции +

c.show();

c= a + b + c;

c.show();

c = b = a;

c.show();

b.show(); }

Как видно, каждая функция-операция имеет только один параметр, в то время как сами функции определяют бинарные операции. Другой аргумент неявно передается с использованием this-указателя. Строка temp.x=x+t.x; аналогична строке temp.x=this->x+t.x;, т.е. х ссылается на this->x. Здесь this ассоциируется с объектом, предшествующим знаку операции. Объект справа от знака операции передается как параметр функции. Если используются функции-члены, то не нужны параметры для унарных операций и требуется лишь один параметр для бинарных операций. Во всех случаях объект, активизирующий операцию, передается в функцию-операцию неявно через указатель this.

Можно также перегрузить операции ++ и --. Это унарные операции. Добавим в пример следующие конструкции:

class vector {

int x,y,z; // координаты

public:

vector operator +(vector t);

vector operator =(vector t);

vector operator++(void); // префиксная операция

vector operator++(int); // постфиксная операция

void show(void);

void assign(int mx, int my, int mz);

};

vector vector::operator ++(void)

{ // префиксная

x++; y++; z++;

return *this;

}

vector vector::operator ++(int)

{ // постфиксная

vector tmp;

tmp=*this;

x++; y++; z++;

return tmp;

}

void main(void)

{

vector a,b,c;

a.assign(1,2,3);

b.assign(4,5,6);

a.show();

b.show();

c=a+b; // использование перегруженной операции +

c.show();

c= a + b + c;

c.show();

c = b = a;

c.show();

b.show();

с++; // использование постфиксной операции

c.show();

++с; // использование префиксной операции

c.show();

}

Данная реализация постфиксной операции содержит важное качество постфиксной операции ++, а именно она увеличивает значение координат вектора на единицу, но возвращает старое значение объекта.