Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекцій по С.doc
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
7.72 Mб
Скачать

5.7 5.8. Довизначення (overloading) операцій

Тепер об'єкт Item можна застосовувати як функцію, що даватиме його вартість

з урахуванням вказаної параметром ставки ПДВ,

int main()

{

Item theWhiteBook( 10.00 );

Item aBMW(60000.00);

//

cout << "Price of theWhiteBook " << theWhiteBook();

cout << "Price of a BMW” << aBMW( 20.00);

return 0;

}

Операція доступу до елементу масиву (індексування). За

її допомогою можна досягти кількох результатів. По-перше, це перевірка виходу

індексу за межі масиву. Ось приклад.

#include <iostream.h>

#include <string.h>

const short kMaxNameLength = 40;

class Name

{

private:

char namestring[ kMaxNameLength ];

short nameLength;

public:

class BadIndex{};

Name( char *name );

void operator()();

char& operator[]( short index );

};

Name::Name( char *name )

{

strcpy( namestring, name );

nameLength = strlen( name );

}

void Name::operator()()

{

cout <<namestring << "\n";

}

char& Name::operator[]( short index )

{

if ( ( index < 0 ) || ( index >= nameLength ) )

throw BadIndex();

return namestring[ index ];

}

Тут, між іншим, ми знову застосували функції-подібні об'єкти.

По-друге, індексування дає можливість створення асоціативних масивів. Ось

клас для підтримки асоціативного масиву пар

#include <iostream.h>

#include <string.h>

const short kMaxNameLength = 40;

class Name

{

private:

char namestring[ kMaxNameLength ];

short nameLength;

public:

class BadIndex{};

Name( char *name );

void operator()();

char& operator[]( short index );

};

Name::Name( char *name )

{

strcpy( namestring, name );

nameLength = strlen( name );

}

void Name::operator()()

{

cout <<namestring << "\n";

}

char& Name::operator[]( short index )

{

if ( ( index <0 ) || ( index >= nameLength ) )

throw BadIndex();

return namestring[ index ];

}

Приклад, що показує застосування асоціативного масиву,

int main()

{

Assoc a;

a.printAll();

a[string("weight")]=1.0;

a[string("high")]=2.0;

a[string("weight")]=3.0;

cout<<A[STRING("WEIGHT")]<<ENDL; pre < } 0; return a.printAll(); a[string(?foo?)]="100;" a[string(?area?)]='a[string("weight")]*a[string("high")];' cout<<a[string(?high?)]<<endl;>

Розумні указники (smart pointers). Якщо зліва від

знаку операції розіменування -> компілятор знаходить указника, то оператор

інтерпретується стандартним чином: виконується операція розіменування. Можна

довизначити розіменування так, щоб першим аргументом цього оператора став об'єкт

певного класу. Так довизначена операція повинна повертати указник. Якщо вона

повертає інший об'єкт, то в його класі знову ж повинна бути довизначене розіменування

і названий процес повторюється знову. Цей механізм називають розумним указником

(smart pointer). Розіменування проходить ланцюжок обєктів, аж поки на

його шляху не зустрічається справжній указник.

#include <iostream>

#include <string>

using namespace std;

const short kMaxNameLength = 40;

class Name

{

private:

char first[ kMaxNameLength ];

char last[ kMaxNameLength ];

public:

Name( char *lastName, char *firstName );

void DisplayName();

};

Name::Name( char *lastName, char *firstName )

{

strcpy( last, lastName );

strcpy( first, firstName );

}

void Name::DisplayName()

{

cout << "Name: " << first << " " << last;

}

class ComputerScientist

{

private:

Name* namePtr;

short age;

public:

ComputerScientist( Name *namePtr, short age );

Name* operator->();

};

ComputerScientist :: ComputerScientist(Name* n, short a )

{

this->namePtr = n;

this->age = a;

}

Name* ComputerScientist::operator->()

{

return( namePtr );

}

int main()

{

Name thePascalAuthor( "Wirth", "Niklaus" );

ComputerScientist Wirth( &thePascalAuthor, 67 );

Wirth->DisplayName();

return 0;

}

Операції, які ми щойно розглянули, взаємозалежні. Дійсно якщо p указник типу

T T* p , то

p->m == (*p).m == p[0].m

Сюди ж належать також операції інкременту і декременту, якщо їх застосовувати

для адресної арифметики. Ось приклад, що ілюструє застосування розумного указника

типу Time

class PtrToTime

{

Time* current;

Time* array;

int size;

public:

class BadIndex{};

PtrToTime(Time *v, int s);

Time* operator->();

Time& operator* ();

Time& operator[](int i);

PtrToTime& operator++();

PtrToTime operator++(int);

PtrToTime& operator--();

PtrToTime operator--(int);

};