
9.Преобразование типа.pptx
- Количество слайдов: 36
9. Преобразование типа
9. 1. Преобразования типа Point -x: double -y: double #print(ostream&): ostream& àvirtual … const friend … operator<< Circle Rectangle -rad: double -len: double -hei: double #print(ostream&): ostream& +area(): double 2
9. 1. Преобразования типа (продолжение) class Point { private: double x, y; protected: virtual std: : ostream & print(std: : ostream &) const; public: // конструкторы friend std: : ostream & oerator <<(std: : ostream &, const Point &); }; 3
9. 1. Преобразования типа (продолжение) class Circle: public Point { private: double rad; protected: std: : ostream & print(std: : ostream &) const; public: // конструкторы double area() const ; }; 4
9. 1. Преобразования типа (продолжение) class Rectangle: public Point { private: double len, hei; protected: std: : ostream & print(std: : ostream &) const; public: // конструкторы double area() const ; }; 5
9. 1. Преобразования типа (продолжение) int main() { Point *p 1; Point pt(2, 3); p 1 = &pt; std: : cout << "*p 1: " << (*p 1) << std: : endl; *p 1: Point: (2, 3) 6
9. 1. Преобразования типа (продолжение) 1. Производный класс в базовый Circle с1(2, 3); p 1 = &c 1; std: : cout << "*p 1: " << (*p 1) << std: : endl; *p 1: Circle: center = Point: (2, 3), radius = 1 7
9. 1. Преобразования типа (продолжение) Rectangle r 1(2, 3); p 1 = &r 1; std: : cout << "*p 1: " << (*p 1) << std: : endl; return 0; } *p 1: Rectangle: top = Point: (2, 3), length = 1, height = 1 Для продолжения нажмите любую клавишу. . . 8
9. 2. Статическое приведение типа 2. Базовый в производный p 1 = new Circle(2, 3); std: : cout << "*p 1: " << (*p 1) << std: : endl; double s = p 1 ->area(); error C 2039: 'area' : is not a member of 'Point' 9
9. 2. Статическое приведение типа (продолжение) std: : cout << "*p 1: " << (*p 1) << std: : endl; Circle *pc = p 1; double s = pc->area(); error C 2440: 'initializing' : cannot convert from 'Point *' to 'Circle *’ 10
9. 2. Статическое приведение типа (продолжение) std: : cout << "*p 1: " << (*p 1) << std: : endl; Circle *pc = (Circle *) p 1; double s = pc->area(); std: : cout << “Circle: s = “ << std: : endl; *p 1: Circle: center = Point: (2, 3), radius = 1 Circle: s = 3. 14159 11
9. 2. Статическое приведение типа (продолжение) std: : cout << "*p 1: " << (*p 1) << std: : endl; Rectangle *pr = (Rectangle *) p 1; double s = pr->area(); std: : cout << "*** Rectangle! s = " << std: : endl; *p 1: Circle: center = Point: (2, 3), radius = 1 *** Rectangle! s = -1. 45682 e+144 12
9. 2. Статическое приведение типа (продолжение) std: : cout << "*p 1: " << (*p 1) << std: : endl; int *pi = (int *) p 1; std: : cout << "int * pi; (*pi) = " << (*pi) << std: : endl; delete p 1; *p 1: Circle: center = Point: (2, 3), radius = 1 int *pi; (*pi) = 4294532 13
9. 2. Статическое приведение типа (продолжение) static_cast<тип> – преобразование между родственными типами данных на этапе компиляции: – указатели в одной и той же иерархии классов – числовые типы данных 14
9. 2. Статическое приведение типа (продолжение) Point *p 1 = new Circle(2, 3); std: : cout << "*p 1: " << (*p 1) << std: : endl; Circle *pc = static_cast<Circle *>(p 1); double s = pc->area(); std: : cout << "Circle: s = " << std: : endl; *p 1: Circle: center = Point: (2, 3), radius = 1 Circle: s = 3. 14159 15
9. 2. Статическое приведение типа (продолжение) std: : cout << "*p 1: " << (*p 1) << std: : endl; Rectangle *pr =static_cast<Rectangle *>(p 1); double s = pr->area(); std: : cout << "*** Rectangle! s = " << std: : endl; *p 1: Circle: center = Point: (2, 3), radius = 1 *** Rectangle! s = -1. 45682 e+144 16
9. 2. Статическое приведение типа (продолжение) std: : cout << "*p 1: " << (*p 1) << std: : endl; int *pi = static_cast<int *>(p 1); std: : cout << "int * pi; (*pi) = " << (*pi) << std: : endl; delete p 1; error C 2440: 'initializing' : cannot convert from ‘Point *' to 'int *' 17
9. 2. Статическое приведение типа (продолжение) Circle *p 1 = new Circle(2, 3); std: : cout << "*p 1: " << (*p 1) << std: : endl; Rectangle *pr = static_cast<Rectangle *> (p 1); double s = pr->area(); std: : cout << "*** Rectangle! s = " << std: : endl; delete p 1; error C 2440: 'static_cast' : cannot convert from 'Circle *' to 'Rectangle *‘ 18
9. 3. Явное приведение типа reinterpret_cast<тип> – преобразование между несвязанными типами на этапе компиляции: – целые и указатели, – несвязанные указатели const_cast<тип> – аннулирует действие модификатора const 19
9. 3. Явное приведение типа (продолжение) Point *p 1 = new Circle(2, 3); std: : cout << "*p 1: " << (*p 1) << std: : endl; int *pi = reinterpret_cast<int *>(p 1); std: : cout << "int * pi; (*pi) = " << (*pi) << std: : endl; delete p 1; *p 1: Circle: center = Point: (2, 3), radius = 1 int *pi; (*pi) = 4294616 20
9. 3. Явное приведение типа (продолжение) Circle c 1(2, 3); std: : cout << "c 1: " << (c 1) << std: : endl; Rectangle *pr = reinterpret_cast<Rectangle *> (&c 1); double s = pr->area(); std: : cout << "*** Rectangle! s = " << std: : endl; c 1: Circle: center = Point: (2, 3), radius = 1 *** Rectangle! s = -1. 45682 e+144 21
9. 3. Явное приведение типа (продолжение) class Point{ private: double x, y; public: . . . Point &move(double dx, double dy) {x += dx; y += dy; return *this; } }; 22
9. 3. Явное приведение типа (продолжение) const Point cp(3, 5); std: : cout << "cp: " << cp << std: : endl; cp. move(2, 6); std: : cout << "cp: " << cp << std: : endl; error C 2662: 'Point: : move' : cannot convert 'this' pointer from 'const Point' to 'Point &’ 23
9. 3. Явное приведение типа (продолжение) const Point cp(3, 5); cout << "cp: " << cp << endl; const_cast<Point &>(cp). move(1, 1); cout << "cp: " << cp << endl; cp: Point: (3, 5) cp: Point: (4, 6) 24
9. 4. Динамическое приведение типа Динамическое приведение указателей на этапе выполнения программы: dynamic_cast<имя_типа *>(операнд) Результат: – корректный указатель, – 0. Используется, когда правильность преобразования не может быть определена компилятором 25
9. 4. Динамическое приведение типа (продолжение) Point *p 1 = new Circle(2, 3); std: : cout << "*p 1: " << (*p 1) << std: : endl; Circle *pc = dynamic_cast<Circle *>(p 1); if(pc){ double s = c 1. area(); std: : cout << " area = " << std: : endl; } 26
9. 4. Динамическое приведение типа (продолжение) else std: : cout << " !!! Illegal conversion !!!" << std: : endl; delete p 1; *p 1: Circle: center = Point: (2, 3), radius = 1 area = 3. 14159 27
9. 4. Динамическое приведение типа (продолжение) Point *p 1 = new Rectangle(2, 3); cout << "*p 1: " << (*p 1) << endl; Circle *pc = dynamic_cast<Circle *>(p 1); . . . *p 1: Rectangle: top = Point: (2, 3), length = 1, height = 1 !!! Illegal conversion !!! 28
9. 4. Динамическое приведение типа (продолжение) Динамическое приведение ссылок на этапе выполнения программы: dynamic_cast<имя_типа &>(операнд) Результат: – корректный объект – исключение std: : bad_cast 29
9. 4. Динамическое приведение типа (продолжение) p 1 = new Circle(2, 3); std: : cout << "*p 1: " << (*p 1) << std: : endl; try{ Circle c 1 = dynamic_cast<Circle &> (*p 1); std: : cout << c 1 << std: : endl; double s = c 1. area(); std: : cout << “ area = " << std: : endl; } 30
9. 4. Динамическое приведение типа (продолжение) catch(std: : bad_cast) { std: : cout << “ !!! Illegal conversion !!!" << std: : endl; } *p 1: Circle: center = Point: (2, 3), radius = 1 area = 3. 14159 31
9. 4. Динамическое приведение типа (продолжение) p 1 = new Rectangle(2, 3); cout << "*p 1: " << (*p 1) << endl; try {. . . *p 1: Rectangle: top = Point: (2, 3), length = 1, height = 1 !!! Illegal conversion !!! 32
9. 4. Динамическое приведение типа (продолжение) . . . Circle c 1 = dynamic_cast<Circle> (*p 1); . . . error C 2680: 'Circle' : invalid target type for dynamic_cast 33
9. 5. Информация о типе #include <typeinfo> typeid(объект). name() – имя типа Circle *p 1 = new Circle(2, 3); cout << typeid(p 1). name() << endl; cout << typeid(*p 1). name() << endl; class Circle * class Circle 34
9. 5. Информация о типе (продолжение) Point *p 1 = new Circle(2, 3); cout << typeid(p 1). name() << endl; cout << typeid(*p 1). name() << endl; class Point * class Circle 35
9. 5. Информация о типе (продолжение) Point *p 1 = new Circle(2, 3); if(typeid(*p 1) == typeid(Circle)) cout << "It is a circle" << endl; It is a circle 36
9.Преобразование типа.pptx