Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

20.1.3. Застосування оператора typeid до шаблонних класів

Оператор typeid можна застосувати і до шаблонних класів. Тип об'єкта, який є примірником шаблонного класу, визначається частково на підставі того, які саме дані використовуються для його узагальнених даних під час реалізації об'єкта. Таким чином, два примірники одного і того ж шаблонного класу, які створюються з використанням різних даних, мають різний тип. Розглянемо простий приклад.

Код програми 20.5. Демонстрація механізму застосування оператора typeid до шаблонних класів

#include <iostream> // Для потокового введення-виведення

#include <cstdlib> // Для використання бібліотечних функцій

using namespace std; // Використання стандартного простору імен

template <class demoClass> class myClass { // Оголошення класового типу

demoClass а;

public:

myClass(demoClass izm) { a = izm;}

//. . .

};

int main()

{

myClass<int> A_ob(10), B_ob(9);

myClass<double> C_ob(7.2);

cout << "Об'єкт A_ob має тип ";

cout << typeid(A_ob).name() << endl;

cout << "Об'єкт B_ob має тип ";

cout << typeid(B_ob).name() << endl;

cout << "Об'єкт C_ob має тип ";

cout << typeid(C_ob).name() << endl;

cout << endl;

if(typeid(A_ob) == typeid(B_ob))

cout << "Об'єкти A_ob і B_ob мають однаковий тип.\n";

if(typeid(A_ob) == typeid(C_ob))

cout << "Помилка\n";

else

cout << "Об'єкти A_ob і C_ob мають різні типи.\n";

getch(); return 0;

}

Внаслідок виконання цієї програми на моніторі буде відображено такі результати:

Об'єкт A_ob має тип class myClass<int>

Об'єкт B_ob має тип class myClass<int>

Об'єкт C_ob має тип class myClass<double>

Об'єкти A_ob і B_ob мають однаковий тип.

Об'єкти A_ob і C_ob мають різні типи.

Як бачите, незважаючи на те, що два об'єкти є примірниками одного і того ж шаблонного класу, якщо їх дані, що параметризуються, не збігаються, то вони не є еквіва|лентними| за типом. У цій програмі об'єкт A_ob має тип myClass<int>, а об'єкт C_ob – тип myClass<double>. Таким чином, це об'єкти різного типу.

Розглянемо ще один приклад застосування оператора typeid до шаблонних класів, а саме модифіковану версію програми визначення геометричних фігур з попереднього підрозділу. Цього разу клас figUre ми зробили шаблонним.

Код програми 20.6. Демонстрація механізму застосування оператора typeid до шаблонної версії figUre-ієрархії класів

#include <iostream> // Для потокового введення-виведення

#include <cstdlib> // Для використання бібліотечних функцій

using namespace std; // Використання стандартного простору імен

template <class demoClass> class figUre {

protected:

demoClass х, y;

public:

figUre(demoClass izm, demoClass jzm) { x = izm; y = jzm;}

virtual demoClass area() = 0;

};

template <class demoClass> class triAngle: public figUre<demoClass> {

public:

triAngle(demoClass izm, demoClass jzm): figUre<demoClass>(izm, jzm) {}

demoClass area() { return x * 0.5 * y; }

};

template <class demoClass> class rectAngle: public figUre<demoClass> {

public:

rectAngle(demoClass izm, demoClass jzm): figUre<demoClass>(izm, jzm) {}

demoClass area() { return x * y;}

};

template <class demoClass> class cirCle: public figUre<demoClass> {

public:

cirCle(demoClass izm, demoClass jzm=0): figUre<demoClass>(izm, jzm) {}

demoClass area() { return 3.14 * x * x;}

};

// Генератор об'єктів, що утворюється з класу figUre.

figUre<double> *generator()

{

switch(rand() % 3) {

case 0: return new cirCle<double>(10.0);

case 1: return new triAngle<double>(10.1, 5.3);

case 2: return new rectAngle<double>(4.3, 5.7);

}

return;

}

int main()

{

figUre<double> *p;

int i;

int t = 0, c = 0, r = 0;

// Генеруємо і підраховуємо об'єкти

for(i=0; i<10; i++) {

p = generator();

cout << "Об'єкт має тип " << typeid(*p).name();

cout << ". ";

// Враховуємо об'єкт

if(typeid(*p) == typeid(triAngle<double>)) t++;

if(typeid(*p) == typeid(rectAngle<double>)) r++;

if(typeid(*p) == typeid(cirCle<double>)) c++;

cout << "Площа дорівнює " << p->area() << endl;

}

cout << endl;

cout << "Згенеровано такі об'єкти:\n";

cout << " трикутників: " << t << endl;

cout << " прямокутників: " << r << endl;

cout << " кругів: " << c << endl;

getch(); return 0;

}

Ось як виглядає можливий результат виконання цієї програми:

Об'єкт має тип class rectAngle<double>. Площа дорівнює 24.51

Об'єкт має тип class rectAngle<double>. Площа дорівнює 24.51

Об'єкт має тип class triAngle<double>. Площа дорівнює 26.765

Об'єкт має тип class triAngle<double>. Площа дорівнює 26.765

Об'єкт має тип class rectAngle<double>. Площа дорівнює 24.51

Об'єкт має тип class triAngle<double>. Площа дорівнює 26.765

Об'єкт має тип class cirCle<double>. Площа дорівнює 314

Об'єкт має тип class cirCle<double>. Площа дорівнює 314

Об'єкт має тип class triAngle<double>. Площа дорівнює 26.765

Об'єкт має тип class rectAngle<double>. Площа дорівнює 24.51

Згенеровано такі об'єкти:

трикутників: 4

прямокутників: 4

кругів: 2

Динамічна ідентифікація типів використовується не у кожній програмі. Але під час роботи з поліморфними типами цей засіб дає змогу дізнатися про тип об'єкта, що обробляється в будь-який довільний момент часу.