Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ЯП_Си++_02_Перегрузка

.pdf
Скачиваний:
14
Добавлен:
12.02.2015
Размер:
292.88 Кб
Скачать

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

Java люблю больше, чем C++, но в ней НЕТ перегрузки операций /

Как разрешить операциям языка C++ работать с объектами? Перегрузить эти операции!

1.«a = b» яснее и удобнее, чем «copy(a,b)».

2.Чтобы перегрузить операцию, надо написать функцию-операцию:

- метод специального вида

Зачем? Из соображений эффективности

 

(чтоб не тратить силы на get- и set-методы)!

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

 

2.1. Перегрузка одноместных (унарных) операций

Еще раз напоминаю: с & не вызы-

 

вается конструктор копирования.

Метод

//

time.h

- параметров нет

Time& operator ++();

- операндом является объект, вызвавший метод

//---------------

time.cpp---------------

Time& Time::operator ++(){ if(second<59) ++second; else { second = 0;

if (minute < 59) ++minute; else { minute = 0;

if(hour < 23) ++hour; else hour = 0;

 

}

 

 

}

 

}

return *this;

main.cpp

//

 

Time t;

 

(++t).printTime();

++t ≈ t.operator ++()

Дружественная функция

//

---------------time.h---------------

 

 

friend Time& operator ++ (Time&);

 

 

//---------------

main.cpp---------------

- один параметр – объект

Time& operator ++(Time& t){

 

if (t.second<59) ++t.second;

(или ссылка на объект) класса.

 

else { t.second = 0;

- операнд – объект-параметр

 

if (t.minute < 59) ++t.minute;

 

 

 

else { t.minute = 0;

 

 

 

if (t.hour < 23) ++t.hour; else t.hour = 0;

 

}

 

 

 

 

}

 

 

 

}

return t;

 

 

main.cpp

 

 

//---------------

 

 

 

Time t;

 

 

 

(++t) .printTime();

++t ≈ t.operator ++(t)

 

Рассмотрели префиксный инкремент. Он предпочтительнее.

Постфиксные инкремент и декремент

Нет & - потери производительности

//---------------

time.h---------------

 

 

Time operator ++ (int);

 

Первый параметр int.

//---------------

time.cpp---------------

Используется только для того, чтобы

Time Time::operator ++ (int){

отличить от префиксной формы.

Time t_old = *this;

 

if(second<59) ++second;

 

else { second = 0;

++minute;

 

if (minute < 59)

 

else {

minute = 0;

 

if(hour < 23) ++hour; else hour = 0;

}

 

 

 

}

 

 

 

return t_old;

 

 

}

main.cpp

 

//---------------

 

Time t;

 

 

 

(t++).printTime(); t++ ≈ t.operator ++(0)

 

2.2. Перегрузка двуместных (бинарных) операций

 

Метод

//

---------------time.h---------------

bool operator > (Time&);

//---------------

time.cpp---------------

bool Time::operator > (Time& t){

int i1

= hour*3600 +

minute*60 + second;

int i2

=

t.hour*3600

+ t.minute*60 + t.second;

if (i1

>

i2)

 

 

return true;

- один параметр – второй (правый) операнд

else

- первым (левым) операндом является

}

return false;

объект, вызвавший метод

main.cpp

//---------------

Time t (10), t1 (20);

 

 

 

if (t > t1) t.printTime();

t > t1 ≈ t.operator >(t1)

 

else

t1.printTime();

 

 

 

Дружественная функция

//---------------

time.h---------------

friend bool operator > (Time&, Time&); t > t1 ≈ operator >(t,t1)

-два параметра – объекты (или ссылки на объекты) класса.

-операнды – объекты-параметры

Хороший стиль программирования:

если не меняются значения полей объекта, то

-лучше делать метод константным

-лучше делать ссылки на объекты-параметры константными

bool operator > (const Time&) const; bool Time::operator > (Time& t) const {

или

friend bool operator > (const Time&, const Time&);

Оба объекта существуют!

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

1.Операция «=» по умолчанию – поэлементное копирование.

2.Когда необходимо перегрузить? См. конструктор копирования!

3.Возвращаемое значение и параметр.

Ссылка на объект, для которого

Ссылка на присваиваемый объ-

эта операция вызвана (левый).

ект (правый).

 

 

 

 

 

 

 

 

Только метод

 

Не наследуется

 

 

 

//

---------------

 

 

 

 

time.h---------------

Time& operator = (const Time&);

//

 

 

 

 

 

 

 

 

 

 

 

 

 

Можно ли убрать эту проверку?

 

 

 

 

 

time.cpp---------------

Time& Time::operator =(const Time& t){

 

 

 

//проверка на самоприсваивание

 

 

 

 

 

 

 

 

if (&t == this) return *this;//сравнение адресов

 

 

 

if (stime) delete[] stime;

 

 

 

 

 

 

 

if (t.stime){

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

stime = new char [strlen(t.stime)+1];

 

 

 

 

strcpy(stime,t.stime);

 

 

 

 

 

} else

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

stime = 0;

 

 

 

 

 

 

 

hour = t.hour;

 

 

 

 

 

 

 

minute = t.minute;

 

 

 

 

second = t.second;

 

 

 

 

 

 

 

 

}

 

return *this;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Эта часть есть в конструкторах

 

Этой части нет в конструкторах

//---------------main.cpp---------------

Time t (10,10,10,"1"), t1, t2; t1.printTime(); t2.printTime();

t2 = t1 = t; //ассоциативность операции «=»? t1.printTime();

t2.printTime();

t1 = t ≈ t1.operator =(t)

2.4. Перегрузка операции приведения типа

Только метод

-нет параметров

-тип возвращаемого значения не указывается

//

time.h

Можно не только

стандартный, но и

operator int();

time.cpp

пользовательский тип

//---------------

 

Time::operator int (){

 

return hour*3600 + minute*60 + second;

 

}

main.cpp

 

//---------------

 

Time t (10,10,10,"1");

printf("%i\n", int(t)); int(t) ≈ t.operator int()

Так же, как и конструктор преобразования, операция приведения типа может вызываться автоматически!

Time t (10,10,10,"1"); printf("%i\n",t);