треугольников: 4

 прямоугольников: 4

 кругов: 2

Применение оператора typeid к шаблонным классам

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

/* Использование оператора typeid с шаблонными классами.

*/

#include

using namespace std;

template

class myclass {

  T a;

 public:

  myclass(T i) { a = i; }

  // . . .

};

int main()

{

 myclass o1(10), o2(9);

 myclass o3(7.2);

 cout << "Объект o1 имеет тип ";

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

 cout << "Объект o2 имеет тип ";

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

 cout << "Объект o3 имеет тип ";

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

 cout << endl;

 if(typeid(o1) == typeid(o2))

  cout << "Объекты o1 и o2 имеют одинаковый тип.\n";

 if(typeid(o1) == typeid(o3)) cout << "Ошибка\n";

 else cout << "Объекты o1 и o3 имеют разные типы.\n";

 return 0;

}

Эта программа генерирует такие результаты.

Объект o1 имеет тип class myclass

Объект o2 имеет тип class myclass

Объект o3 имеет тип class myclass

Объекты o1 и o2 имеют одинаковый тип.

Объекты o1 и o3 имеют разные типы.

Как видите, несмотря на то, что два объекта являются экземплярами одного и того же шаблонного класса, если их параметризованные данные не совпадают, они не эквивалентны по типу. В этой программе объект o1 имеет тип myclass, а объект o3 — тип myclass. Таким образом, это объекты разного типа.

Рассмотрим еще один пример применения оператора typeid к шаблонным классам, а именно модифицированную версию программы определения геометрических фигур из предыдущего раздела. На этот раз класс figure мы сделали шаблонным.

// Шаблонная версия figure-иерархии.

#include

#include

using namespace std;

template

class figure

{

 protected:

  T x, y;

 public:

  figure(T i, T j) {

   x = i;

   у = j;

  }

  virtual T area() = 0;

};

template

class triangle : public figure

{

 public:

  triangle(T i, T j) : figure(i, j) {}

  T area() {

   return x * 0.5 * y;

  }

};

template

class rectangle : public figure

{

 public:

  rectangle(T i, T j) : figure(i, j) {}

  T area() {

   return x * y;

  }

};

template

class circle : public figure

{

 public:

  circle(T i, T j=0) : figure(i, j) {}

  T area() {

   return 3.14 * x * x;

  }

};

// Фабрика объектов, генерируемых из класса figure.

figure *generator()

{

 switch(rand() % 3 ) {

  case 0: return new circle (10.0);

  case 1: return new triangle(10.1, 5.3);

  case 2: return new rectangle (4.3, 5.7);

 }

 return 0;

}

int main()

{

 figure *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)) t++;

  if(typeid(*p) == typeid(rectangle)) r++;

  if(typeid(*p) == typeid(circle)) c++;

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

 }

 cout << endl;

 cout << "Сгенерированы такие объекты:\n";

 cout << " треугольников: " << t << endl;

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги