Run Time Type Information Binary files RTTI why
Run Time Type Information, Binary files
RTTI – why? Problem: • Up-casting works fine. Shape Line – Treating sub-class as base class Shape * s = new Circle(); • What about down-casting? – might not be safe ! – correctness cannot be determined by the compiler. Circle * c = (Circle*) s; Circle
RTTI – Run Time Type Information Mechanisms for RTTI: 1. dynamic_cast operator 2. typeid operator (and type_info class)
The ‘dynamic_cast‘ operator dynamic_cast<T>(expression) u. Enables run-time type checking: · returns a valid pointer if “expression” is of type “T” · Null pointer 0 otherwise u. Cast of a reference type throws an exception when it fails (“bad_cast”)
Dynamic_cast : example Shape* s = container. pop(); Circle* c = dynamic_cast<Circle*>(s); if (c) { // c is a circle c->do. Something(); else handle(); //handle unexpected event Note: the actual type of “s” is not mentioned! – Can be any sub-class of Circle.
Example Shape s; Circle c; Circle Line l; Thin. Line tl; Shape* arr[4] = {&s, &c, &l, &tl}; Thick. Line for ( int i=0; i<3; i++ ) { Line * pl = dynamic_cast<Line*>( arr[i] ); pc? cout << “cast okn” : cout << “cast failn”; } Output: cast fail cast ok // Shape to Line // Circle to Line // Line to Line // Thick. Line to Line
dynamic_cast - more dynamic_cast<T>(expression) Note: u. Used only on pointer or reference types. u. Can be used for up-cast, down-cast u and also for cross-cast (out of this scope) u. Only for types with virtual-functions (“Polymorphic types”) u These object have a space for the information about the type: the virtual function table
dyn_cast: only for polymorphics class Date : public Time { … // Time has no virtual functions } class Circle : public Shape { virtual void draw(); … } void foo(Shape * s, Time * t) { Circle * c = dynamic_cast<Circle*>( s ); Date * date = dynamic_cast<Date*>( t ); } //ok //error
Static Cast • Used when the compiler cannot assume anything about the memory pointed to by a void*. This implies that dynamic cast cannot cast from a void*. For that, a static cast is needed. R* f(void *p) { S ps = static_cast<S*> (p); } //trust the programmer.
RTTI : typeid operator • Obtains info about an object/expression • usage: typeid( obj ) (like “sizeof”) Example: Dog d; Cat c; cout << “d is a “ << typeid(d). name() << “, ” << “c is a “ << typeid(c). name() <<endl; Output: d is a Dog, c is a Cat typeid() returns a reference to a standard library type called type_info defined in <type-info>.
type_info class • typeid(expression) returns an object of the type_info class. • e. g. type_info& ti = typeid(d); class type_info { public: bool operator==( type_info const&)const; char const* name() const; … private: type_info( type_info const&); //prevent copying type_info& operator=( type_info const& ); }
RTTI misuse void rotate( shape const& s ) { if (typeid(s) == typeid(Circle) ) //do nothing else if (typeid(s) == typeid(Triangle) ) //rotate Triangle else if (typeid(s) == typeid(Rectangle) ) //rotate Rectangle … } • Use virtual functions (polymorphism) when you can ! • VERY common misuse of RTTI
Binary files
Leading example: image files • Images are stored as matrices of numbers (Pixels). • Here, we deal with gray-scale images (“black and white”) • 8 bits per pixel – i. e. each pixel between 0 and 255 • 0 is white, 255 is black, others are gray 255 0 0 0 255 100
storing images • How can we store images on files? • For each image we want to store: – width //integer – height //integer – number of bits per pixel //short – the pixels //matrix of integers • Requirements: read/write easily, save space, save computation, etc.
storing images First try: text files (like you did so far) cons: pros: u long u readable by humans u easy to edit u needs parsing (e. g. u but who handles atoi for numbers) “my. Img. txt” width = 3 height = 2 bits_per_pixel = 8 255, 0, 0 0, 255, 100 images like that?
Binary files Better solution: Binary files u Save the data the way the computer holds it pros: u Smaller u No parsing (faster) u Widely u cons: u hard to read for humans u Machine dependant used ! For example: BMP files, other data
Images as binary files width 2 bytes [0, …, 0, 0, 1, 1] height 2 bytes [0, …, 0, 0, 1, 0] 3 2 8 255 0 0 0 255 100
Images as binary files 3 2 bits per pixel 1 byte [0, 0, 1, 0, 0, 0] 8 255 0 0 0 255 100
Images as binary files pixel 1 byte [1, 1, 1] pixel 1 byte [0, 0, 0] 3 2 8 255 0 0 0 255 100
Binary files 3 2 16 255 bits per pixel now value 16 0 0 255 0 0
Example: writing a binary file Pixel pixs[30]; int width = 100, height = 150; short bits. Per. Pix = 16; binary open for writing ofstream outfile; outfile. open(“pic. raw", ios: : bin | ios: : out); outfile. write(&width, sizeof(int)); outfile. write(&height, sizeof(int)); outfile. write(&bits. Per. Pix, sizeof(short)); outfile. write(pixs, 30*sizeof(Pixel)); outfile. close(); ostream& write( char const* str, streamsize n);
Learn by yourselves: c++ casting (see slides ahead and Stroustrup 15. 4 and more)
c++ style casting • At the beginning c++ supported two styles of casts: – (typename)expression – typename(expression) • Instead there are now four new casting operators: – – static_cast<type>(expression) const_cast<type>(expression) reinterpret_cast<type>(expression) dynamic_cast<type>(expression)
The 'static_cast operator static_cast<type>(expression) • Works where implicit conversion exists – standard or user-defined conversion – up-casts • Safer that “old-style” casts – e. g. won’t cast int* to float* • Failure causes a compiler error – No dynamic checking is done!
The ‘const_cast'operator const_cast<type>(expression) • Is used to remove (or add) const-ness: void g(C * cp); void f(C const* cp) { g(const_cast<C *>(cp)); } • Usually, you should design your variables/methods such that you won’t have to use const_cast. • Failure causes compiler errors
‘reinterpret_cast'operator reinterpret_cast<type>(expression) • Is used to reinterpret byte patterns. double d(10. 2); char* d. Bytes = reinterpret_cast<char *>(&d); • • • ! Circumvents the type checking of c++. Very implementation-dependent. Rarely used. Very dangerous !
- Slides: 27