Standard C Programarea calculatoarelor i limbaje de programare
Standard C++ Programarea calculatoarelor şi limbaje de programare II Capitolul 12
Obiective n Înţelegerea modului în care se folosesc operatorii static_cast, const_cast şi reinterpret_cast n Înţelegerea şi folosirea Run-time type information (RTTI) şi a operatorilor typeid şi dynamic_cast
Introducere n Conversia unui tip de dată în alt tip de dată se numeşte type-cast n n conversia implicită conversia explicită n Pentru conversia implicită nu este nevoie de un operator de cast n se face automat la copierea unei valori într-o locaţie de memorie care un tip compatibil n Exemplu short a=2000; int b; b=a;
Introducere n Conversia implicită se face şi prin apelul operatorilor de conversie ai claselor care sunt constructorii cu un singur parametru n Exemplu class A {}; class B { public: B (A a) {} }; A a; B b=a;
Introducere n Conversiile care necesită o interpretare diferită a unei valori trebuie realizate prin conversie explicită care se poate specifica în două modalităţi n Exemplu short a = 2000; int b; b = (int) a; b = int (a);
Introducere n Uneori, însă, deşi codul este corect din punct de vedere sintactic, pot apărea erori la rulare sau rezultate aleatoare n Exemplu #include <iostream> using namespace std; class A { float i, j; }; class B { int x, y; public: B (int a, int b) { x=a; y=b; } int result() { return x+y; } };
Introducere int main () { A d; B * padd; padd = (B*) &d; cout << padd->result(); return 0; } Cast-ul din C permite conversia unui pointer într-un pointer de alt tip Rularea acelei secvenţe de cod poate produce o eroare sau rezultate ale unor operaţii cu valori aleatoare din memorie
Sumar n Operatorul static_cast n Operatorul const_cast n Operatorul reinterpret_cast n Run-Time Type Information (RTTI) n Operatorul typeid n Operatorul dynamic_cast
Operatorul static_cast n Limbajul C++ standard conţine patru operatori de cast care sunt de preferat celor folosiţi de versiunile mai vechi ale limbajelor C şi C++ n static_cast n const_cast n reinterpret_cast n dynamic_cast n Aceşti operatori dau programatorului un control mai precis asupra operaţiilor de cast care se ştie că sunt adeseori o sursă de erori în timpul rulării unui program n Aceşti operatori de cast se folosesc în contexte bine definite n vechii operatori sunt universali
Operatorul static_cast n Operatorul static_cast pentru conversiile standard şi inversele lor n Operatorul static_cast permite conversiile standard, de exemplu void* la char* sau int la double, şi inversele lor
Operatorul static_cast. . . class Base. Class { public: void f() const { cout << "BASEn"; } }; class Derived. Class : public Base. Class { public: void f() const { cout << "DERIVEDn"; } }; void test(Base. Class*); int main() {. . . }
Operatorul static_cast. . . int main() { double d = 8. 22; int x = static_cast<int>(d); Se foloseşte static_cast pentru conversie cout << "d este " << d << "nx este " << x << endl; Base. Class *base. Ptr = new Derived. Class; test(base. Ptr); delete base. Ptr; return 0; cast de la pointer la clasa de bază la pointer la clasa derivată - downcasting } void test(Base. Class *base. Ptr) { Derived. Class *derived. Ptr; derived. Ptr = static_cast<Derived. Class*>(base. Ptr); derived. Ptr->f(); //functia f din Derived. Class }
Sumar n Operatorul static_cast n Operatorul const_cast n Operatorul reinterpret_cast n Run-Time Type Information (RTTI) n Operatorul typeid n Operatorul dynamic_cast
Operatorul const_cast n Operatorul const_cast pentru a permite modificarea unor date const sau volatile n Exemplu class Const. Cast. Test { public: void set. Number(int); int get. Number() const; void print. Number() const; private: int number; };
Operatorul const_cast void Const. Cast. Test: : set. Number(int num) { number = num; } int Const. Cast. Test: : get. Number() const { return number; } void Const. Cast. Test: : print. Number() const { cout << "n. Numarul dupa modificare: "; const_cast<Const. Cast. Test*>(this)->number--; cout << number << endl; } Expresia number-- ar genera eroare la compilare const_cast face modificarea posibila
Operatorul const_cast int main() { Const. Cast. Test x; x. set. Number(8); cout << "Valoarea initiala a numarului: " << x. get. Number(); x. print. Number(); return 0; } Valoarea initiala a numarului: 8 Numarul dupa modificare: 7
Operatorul const_cast n Exemplu #include <iostream> using namespace std; void print (char * str) { cout << str << endl; } int main () { const char * c = "Sir constant"; print ( const_cast<char *> (c) ); return 0; } Sir constant
Sumar n Operatorul static_cast n Operatorul const_cast n Operatorul reinterpret_cast n Run-Time Type Information (RTTI) n Operatorul typeid n Operatorul dynamic_cast
Operatorul reinterpret_cast n Conversiile nestandard pot fi implementate în C++ prin operatorul reinterpret_cast n Exemplu n Poate fi folosit pentru conversia de la un pointer de un tip la un pointer de alt tip n Nu poate fi folosit pentru conversiile standard, de exemplu de la double la int
Operatorul reinterpret_cast #include <iostream> reinterpret_cast îl converteşte using std: : cout; pe ptr de la int* la tipul char* using std: : endl; #include <queue> int main() { int x = 85, *ptr = &x; cout << *reinterpret_cast<char*>(ptr) << endl; return 0; } U
Sumar n Operatorul static_cast n Operatorul const_cast n Operatorul reinterpret_cast n Run-Time Type Information (RTTI) n Operatorul typeid n Operatorul dynamic_cast
Run-Time Type Information (RTTI) n Run-time tipe information (RTTI) oferă o modalitate de determinare a tipului unui obiect în timpul rulării programului n Foloseşte doi operatori importanţi typeid n dynamic_cast n
Operatorul typeid. . . #include <typeinfo> template <class T> T maximum(T value 1, T value 2, T value 3) { T max = value 1; typeid(T). name() if(value 2 > value 1) max = value 2; if(value 3 > max) max = value 3; const char* data. Type = typeid(T). name(); cout << "Au fost comparate de tip " << data. Type << "n. Cel mai mare " << data. Type << " este "; return max; }
Operatorul typeid int main() { int a = 8, b = 88, c = 22; double d = 95. 96, e = 78. 59, f = 83. 99; cout << maximum(a, b, c) << "n"; cout << maximum(d, e, f) << endl; return 0; } Au fost Cel mai comparate de tip int mare int este 88 comparate de tip double mare double este 95. 96
Operatorul dynamic_cast n Operatorul dynamic_cast se foloseşte pentru implementarea conversiilor care au loc în timpul rulării programului şi pe care compilatorul nu le poate verifica n Acest operator este folosit, de regulă, pentru downcasting de la un pointer la clasa de bază către un pointer la clasa derivată n El poate fi folosit doar pentru pointeri sau referinţe la obiecte n RTTI este proiectat să fie folosit în ierarhii de moştenire care implementează comportamente polimorfice
Operatorul dynamic_cast class Shape { public: virtual double area() const { return 0. 0; } }; class Circle : public Shape { public: Circle(int r = 1) { radius = r; } virtual double area() const { return PI * radius; } protected: int radius; };
Operatorul dynamic_cast class Cylinder : public Circle { public: Cylinder(int h = 1) { height = h; } virtual double area() const { return 2 * PI * radius * height + 2 * Circle: : area(); } private: int height; };
Operatorul dynamic_cast void output. Shape. Area(const Shape* shape. Ptr) { const Circle *circle. Ptr; const Cylinder *cylinder. Ptr; cylinder. Ptr = dynamic_cast<const Cylinder*>(shape. Ptr); if(cylinder. Ptr != 0) cout << "Aria cilindrului: " << shape. Ptr->area(); else { circle. Ptr = dynamic_cast<const Circle*>(shape. Ptr); if(circle. Ptr != 0) cout << "Aria cercului: " << circle. Ptr->area(); else cout << "Nu este nici Circle, nici Cylinder. "; } cout << endl; }
Operatorul dynamic_cast int main() { Circle circle; Cylinder cylinder; Shape *ptr = 0; output. Shape. Area(&circle); output. Shape. Area(&cylinder); output. Shape. Area(ptr); return 0; } Aria cercului: 3. 14159 Aria cilindrului: 12. 5664 Nu este nici Circle, nici Cylinder.
- Slides: 29