|
итоговый отчет 1. Лабораторная работа 2 Классы. Основы 12 Лабораторная работа 3 Классы. Инкапсуляция 16
Лабораторная работа №4 Приведение типов. RTTI
Цель работы:приобретение практических навыков использования механизмов приведения типов и определения типа объекта во время выполнения программы (Run-Time Type Identification, RTTI) на языке C++ с применением следующих операторов:
1.
2.
3.
4. typeid()
1. Задание для работы
Построить иерархию классов:
Shape (Фигура) -> Circle (Эллипс) -> Torus (Тор)
Продемонстрировать приведение типов и ошибки, которые могут при этом возникать.
Код программы на языке C++
В результате выполнения задания была разработана программа на языке C++, код которой приведен ниже:
//файл main.cpp
#include "stdafx.h"
#include
#include
#include using namespace std; //Класс Shape
class Shape {
protected:
double square; public:
Shape() {
square = 0;
}
double GetSquare() const {
return square;
}
virtual string InfoObject() const {
return "Object Shape.";
}
string InfoPointer() const {
return "Pointer Shape.";
}
friend ostream & operator << (ostream & out,
const Shape & a);
}; //Класс Circle
class Circle : public Shape
{
protected:
int radius;
public:
Circle()
{
radius = 7;
square = 3.1415*radius*radius;
}
string InfoObject() const
{
return "Object Circle.";
}
string InfoPointer() const
{
return "Pointer Circle.";
}
}; // класс Torus
class Torus: public Circle {
private: double volume, R, r;
public: Torus() {
volume = 2 * 3.1415 * 3.1415 * R * r * r;
}
string InfoObject() const {
return "Object Torus.";
}
string InfoPointer() const {
return "Pointer Torus.";
}
void Derived_Method() {
cout << "Torus is derived of Circle\n";
}
};
ostream & operator << (ostream & out, const Shape & a) {
return out << "Square= " << a.GetSquare();
}
int _tmain(int argc, _TCHAR * argv[]) {
setlocale(LC_ALL, "Russian");
Shape * shape = new Shape();
Circle * circle = new Circle();
Torus * torus = new Torus();
cout << "-----------------STATIC_CAST--------------\n";
cout << " Восходящее \n\n";
cout << "1) Shape* shape1 = static_cast(circle);\n\n";
Shape * shape1 = static_cast < Shape * > (circle);
cout << "Before: \t\tAfter: \t\t\ttypeid\n";
cout << ( * circle).InfoPointer() << "\t""\t" << ( * shape1).InfoPointer() <<"\t\t"
<< typeid(shape1).name() << endl;
cout << ( * circle).InfoObject() << "\t""\t" << ( * shape1).InfoObject() << endl;
cout << * circle << "\t" << * shape1 << endl << endl;
cout << "2) Shape* shape2 = static_cast(torus);\n\n";
Shape * shape2 = static_cast < Shape * > (torus);
cout << "Before: \t\tAfter: \t\t\ttypeid\n";
cout << ( * torus).InfoPointer() << "\t""\t" << ( * shape2).InfoPointer() << "\t\t"
<< typeid(shape2).name() << endl;
cout << ( * torus).InfoObject() << "\t\t" << ( * shape2).InfoObject() << endl;
cout << * torus << "\t\t" << * shape2 << endl << endl;
cout << " Нисходящее \n\n";
cout << "3) Rectangle* circle1 = static_cast(torus);\n\n";
Circle * circle1 = static_cast < Circle * > (torus);
cout << "Before: \t\tAfter: \t\t\ttypeid\n";
//circle1->Derived_Method();
//Класс потомок приводится к классу родителю с потерей полей.
cout << ( * torus).InfoPointer() << "\t" << ( * circle1).InfoPointer() <<"\t" <<
typeid(circle1).name() << endl;
cout << ( * torus).InfoObject() << "\t\t" << ( * circle1).InfoObject() < cout << * torus << "\t\t" << * circle1 << endl;
cout << "\nrectangle1->Derived_Method();\nКласс потомок приводится к классу
родитель с потерей полей.\n\n";
cout << "-----------------DYNAMIC_CAST--------------\n";
cout << " Восходящее \n\n";
cout << "4) Shape* shape3 = dynamic_cast(circle);\n\n";
Shape * shape3 = dynamic_cast < Shape * > (circle);
cout << "Before: \t\tAfter: \t\t\ttypeid\n";
cout << ( * circle).InfoPointer() << "\t" << ( * shape3).InfoPointer() << "\t\t" <<
typeid(shape3).name() << endl;
cout << ( * circle).InfoObject() << "\t" << ( * shape3).InfoObject() << endl;
cout << * circle << "\t\t" << * shape3 << endl << endl;
cout << "5) Shape* shape4 = dynamic_cast(torus);\n\n";
Shape * shape4 = dynamic_cast < Shape * > (torus);
cout << "Before: \t\tAfter: \t\t\ttypeid\n";
cout << ( * torus).InfoPointer() << "\t" << ( * shape4).InfoPointer() <<"\t\t" <<
typeid(shape4).name() << endl;
cout << ( * torus).InfoObject() << "\t\t" << ( * shape4).InfoObject() < cout << * torus << "\t\t" << * shape4 << endl << endl;
cout << " Нисходящее \n\n";
cout << "6) Circle* circle2 = dynamic_cast(shape);\n";
Circle * circle2 = dynamic_cast < Circle * > (shape);
if (circle2 == NULL) {
cout << "typeid(circle2):" << typeid(circle2).name() << endl;
cout << "Not converted. Pointer==NULL." << endl;}
try {
cout << "\n Ссылки \n";
cout << "\n7) Circle& circle3=*circle;\n Sphere&torus1=dynamic_cast(circle3);\n";
Circle & circle3 = * circle;
Torus & torus1 = dynamic_cast < Torus & > (circle3);
cout << "typeid(pyramid1):" << typeid(torus1).name() << endl;
} catch (bad_cast & e) {
cout << endl << e.what() << endl;
cout << "\n--------------------CONST_CAST----------------\n";
cout << "\n8) const Circle& circle3 = Circle();\n const Shape& shape5 =
dynamic_cast(circle3);\nShape& shape6 = const_cast(shape5);\n";
const Circle & circle3 = Circle();
const Shape & shape5 = dynamic_cast <
const Shape & > (circle3);
Shape & shape6 = const_cast < Shape & > (shape5);
cout << "\ntypeid(shape6): " << typeid(shape6).name() << endl;
cout << "\n9) const Sphere& torus2 = Sphere();\n const Circle& circle4 =
dynamic_cast(torus2);\nconst Shape& shape7 = dynamic_cast Shape&>(torus2);\n";
const Torus & torus2 = Torus();
const Circle & circle4 = dynamic_cast < const Circle & > (torus2);
const Shape & shape7 = dynamic_cast < const Shape & > (torus2);
cout << "\ntypeid(shape7): " << typeid(shape7).name() << endl;
system("pause");
return 0;
}
Результат работы программы на языке C++
-----------------STATIC_CAST--------------
Восходящее 1) Shape* shape1 = static_cast(circle);
Before: After: typeid
Pointer Circle. Pointer Shape. class Shape *
Object Circle. Object Circle.
Square= 153.934 Square= 153.934 2) Shape* shape2 = static_cast(torus);
Before: After: typeid
Pointer Torus. Pointer Shape. class Shape *
Object Torus. Object Torus.
Square= 153.934 Square= 153.934
Нисходящее 3) Rectangle* circle1 = static_cast(torus);
Before: After: typeid
Pointer Torus. Pointer Circle. class Circle *
Object Torus. Object Torus.
Square= 153.934 Square= 153.934
rectangle1->Derived_Method(); Класс потомок приводится к классу родитель с потерей полей.
-----------------DYNAMIC_CAST-------------- Восходящее 4) Shape* shape3 = dynamic_cast(circle);
Before: After: typeid
Pointer Circle. Pointer Shape. class Shape *
Object Circle. Object Circle.
Square= 153.934 Square= 153.934
5) Shape* shape4 = dynamic_cast(torus);
Before: After: typeid
Pointer Torus. Pointer Shape. class Shape *
Object Torus. Object Torus.
Square= 153.934 Square= 153.934
Нисходящее 6) Circle* circle2 = dynamic_cast(shape);
typeid(circle2):class Circle *
Not converted. Pointer==NULL.
Ссылки 7) Circle& circle3=*circle;
Sphere& torus1=dynamic_cast(circle3);
Bad dynamic_cast! --------------------CONST_CAST----------------
8) const Circle& circle3 = Circle();
const Shape& shape5 = dynamic_cast(circle3);
Shape& shape6 = const_cast(shape5);
typeid(shape6): class Circle
9) const Sphere& torus2 = Sphere();
const Circle& circle4 = dynamic_cast(torus2);
const Shape& shape7 = dynamic_cast(torus2);
typeid(shape7): class Torus
Для продолжения нажмите любую клавишу . . .
|
|
|