1 / 58

Introduzione ai linguaggi compilati orientati ad oggetti

Introduzione ai linguaggi compilati orientati ad oggetti. Alessandra Doria, Napoli Vincenzo Innocente , CERN Luca Lista, Napoli. Programmazione procedurale. Uno dei principali problemi del software è la sua evoluzione e la sua manutenzione

molly
Download Presentation

Introduzione ai linguaggi compilati orientati ad oggetti

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduzione ai linguaggi compilati orientati ad oggetti Alessandra Doria, Napoli Vincenzo Innocente, CERN Luca Lista, Napoli Vincenzo Innocente - Corso breve OO

  2. Programmazione procedurale • Uno dei principali problemi del software è la sua evoluzione e la sua manutenzione • specialmente in grossi progetti come un esperimento di HEP • Esempi con linguaggi procedurali (Fortran): • Cosa succede quando il codice viene modificato • Dipendenze all’interno del codice Vincenzo Innocente - Corso breve OO

  3. Un esempio semplice • Un esempio “elegante”: copiare una sequenza di caratteri dalla tastiera alla stampante SUBROUTINE COPY LOGICAL READKB CHARACTER C DO WHILE (READKB(C)) CALL WRTPRN(C) ENDDO RETURN • Questo codice dovrà prima o poi essere modificato (aggiornamenti, estensioni, richieste dagli utenti, ecc.) Vincenzo Innocente - Corso breve OO

  4. Modifiche dei requisiti • Una modifica un po’ meno elegante:scrivere anche su un file SUBROUTINE COPY(FLAG) LOGICAL READKB INTEGER FLAG CHARACTER C DO WHILE (READKB(C)) IF (FLAG .EQ. 1) CALL WRTPRN(C) ELSE CALL WRTFL(C) ENDIF ENDDO RETURN Vincenzo Innocente - Corso breve OO

  5. Evoluzione incontrollata SUBROUTINE COPY(FLAG1, FLAG2) LOGICAL READKB, READFL INTEGER FLAG1, FLAG2 LOGICAL CONT CHARACTER C 10 IF (FLAG1 .EQ. 1) THEN CONT = READKB(C) ELSE CONT = READFL(C) ENDIF IF (CONT) THEN IF (FLAG2 .EQ. 1) THEN CALL WRTPRN(C) ELSE CALL WRTFL(C) ENDIF GOTO 10 ENDIF RETURN • Un’altra modifica per niente elegante:leggere anche de un file Vincenzo Innocente - Corso breve OO

  6. Descrizione dei dati Idea: perché non usare una function? • Esempio: cinematica relativistica COMMON /MYDATA/ P1(4), P2(4), + P3(4), P4(4) REAL P1(4), P2(4), P3(4), P4(4) COSTHETA12 = (P1(1)*P2(1) + P1(2)*P2(2) + + P1(3)*P2(3))/... COSTHETA13 = (P1(1)*P3(1) + P1(2)*P3(2) + + P1(3)*P3(3))/... COSTHETA14 = (P1(1)*P4(1) + P1(2)*P4(2) + + P1(3)*P4(3))/... FUNCTION COSTHETA(P1, P2) REAL P1(4), P2(4) COSTHETA = (P1(1)*P2(1) + P1(2)*P2(2) + + P1(3)*P2(3))/... END COMMON /MYDATA/ P1(4), P2(4), + P3(4), P4(4) REAL P1(4), P2(4), P3(4), P4(4) COSTHETA12 = COSTHETA(P1, P2) COSTHETA13 = COSTHETA(P1, P3) COSTHETA14 = COSTHETA(P1, P4) Vincenzo Innocente - Corso breve OO

  7. Evoluzione del codice • Se cambia il formato del common block? COMMON /MYDATA/ P1(4), P2(4), + P3(4), P4(4) COMMON /MYDATA/ P(4), E(4), + THETA(4), PHI(4) • Bisogna cambiare la funzione (gli argomenti sono diversi) FUNCTION COSTHETA1(THETA1, THETA2, + PHI1, PHI2) COSTHETA1 = SIN(THETA1)*SIN(THETA2) * + COS(PHI1-PHI2) + COS(THETA1)*COS(THETA2) END • …e il codice! COMMON /MYDATA/ P(4), E(4), + THETA(4), PHI(4) COSTHETA12 = COSTHETA1(THETA(1),THETA(2), + PHI(1), PHI(2)) COSTHETA13 = COSTHETA1(THETA(1),THETA(3), + PHI(1), PHI(3)) COSTHETA14 = COSTHETA1(THETA(1),THETA(4), + PHI(1), PHI(4)) Vincenzo Innocente - Corso breve OO

  8. Il concetto di dipendenza • Nell’esempio precedente il codice di analisi (“alto livello”) dipende dai dettagli della struttura dati (“basso livello”). FUNCTION COSTHETA(P1, P2) REAL P1(4), P2(4) COSTHETA = (P1(1)*P2(1) + P1(2)*P2(2) + + P1(3)*P2(3))/... END COSTHETA dipende dalla struttura dei dati P1 e P2 COMMON /MYDATA/ P1(4), P2(4), + P3(4), P4(4) COSTHETA12 = COSTHETA(P1, P2) COSTHETA13 = COSTHETA(P1, P3) COSTHETA14 = COSTHETA(P1, P4) Il codice di analisi dipende dalla struttura del common block MYDATA Vincenzo Innocente - Corso breve OO

  9. C++/Object Oriented • Riduce la dipendenza del codice di alto livello dalla rappresentazione dei datiPermette il riutilizzo del codice di alto livello • Nasconde i dettagli di implementazione Vincenzo Innocente - Corso breve OO

  10. Kalman.inc Filter.f PARAMETER (NPLAN = 8, NSTOP = NPLAN-1, + NSTOP5 = 5*NPLAN ) COMMON /GCFIT/ + CSIX(6,0:NSTOP),CSIY(6,0:NSTOP) + ,CSIZ(6,0:NSTOP) + ,WW(5,5,0:NSTOP),DDT(5,5,0:NSTOP) + ,VV(5,5,0:NSTOP),SS(5,5,0:NSTOP) + ,CC(5,5,0:NSTOP) + ,CHI2,CHI2N,CHI2T,CHI2M + ,PLANI(3,4,0:NSTOP) DOUBLE PRECISION + CSIX ,CSIY ,CSIZ + ,WW ,DDT + ,VV ,SS + ,CC + ,CHI2,CHI2N,CHI2T,CHI2M SUBROUTINE FILTER(JSTOP,IFAIL) INTEGER JSTOP, IFAIL #include “Kalman.inc” DOUBLE PRECISION YDUM(5) * ** filter * CALL DVADD(25,WW(1,1,JSTOP),WW(2,1,JSTOP), + VV(1,1,JSTOP),VV(2,1,JSTOP), + CC(1,1,JSTOP),CC(2,1,JSTOP)) CALL DSINV(5,CC(1,1,JSTOP),5,IFAIL) IF ( IFAIL.NE.0 ) THEN 1 PRINT *,'DSINV IFAIL',IFAIL,' AT PLANE ',JSTOP CALL VZERO(CC(1,1,JSTOP),50) RETURN ENDIF CALL DMMPY(5,5,VV(1,1,JSTOP),VV(1,2,JSTOP),VV(2,1,JSTOP), + CSIZ(1,JSTOP),CSIZ(2,JSTOP), + YDUM(1), YDUM(2)) CALL DMMPA(5,5,WW(1,1,JSTOP),WW(1,2,JSTOP),WW(2,1,JSTOP), + CSIY(1,JSTOP),CSIY(2,JSTOP), + YDUM(1), YDUM(2)) CALL DMMPY(5,5,CC(1,1,JSTOP),CC(1,2,JSTOP),CC(2,1,JSTOP), + YDUM(1), YDUM(2), + CSIX(1,JSTOP),CSIX(2,JSTOP)) CSIX(6,JSTOP) = CSIY(6,JSTOP) * CHI2 DO J = 1,5 DO K=1,5 CHI2 = CHI2 + + (CSIX(K,JSTOP)-CSIZ(K,JSTOP))*VV(K,J,JSTOP)* + (CSIX(J,JSTOP)-CSIZ(J,JSTOP)) + + (CSIX(K,JSTOP)-CSIY(K,JSTOP))*WW(K,J,JSTOP)* + (CSIX(J,JSTOP)-CSIY(J,JSTOP)) ENDDO ENDDO * END Dati globali Modello dei dati esplicito Sintassi oscura Tipo non controllato Vincenzo Innocente - Corso breve OO

  11. KalmanStep.h KalmanStep.cc class KalmanStep { public: bool propagate(const KalmanStep& previous); bool filter() ; bool smooth(const KalmanStep& next); private: Vector5 csix; SimMatrix5 cc; SimMatrix5 ss; Vector5 csiy; SimMatrix5 ww; Vector5 csiz; SimMatrix5 vv; Matrix5 ddt; Plane plane; double chi2; }; bool KalmanStep::filter() { bool fail = false; cc = ww+vv; cc.invert(fail); if (fail) { cc.zero(); return !fail;} csix = cc*(vv*csiz + ww*csiy); chi2 += (csix-csiz)*vv*(csix-csiz)+ (csix-csiy)*ww*(csix-csiy); return !fail; } Tipo controllato o convertito Sintassi “naturale” Modello dei dati nascosto Dati incapsulati Vincenzo Innocente - Corso breve OO

  12. Classi e oggetti • Definizione di nuovi tipi (oltre a int, float, double) come: • numeri complessi, • vettori, • matrici, . . . • ma anche: • tracce, • superfici, • elementi di rivelatori, • cluster, . . . • Gli oggetti permettono di modellare una problema che rappresenti la realtà Vincenzo Innocente - Corso breve OO

  13. Concetti base dell’OO • Classi ed oggetti • Incapsulamento • Relazione di ereditarietà • Polimorfismo • Programmazione Generica (C++) Vincenzo Innocente - Corso breve OO

  14. Classi e Oggetti • Un esempio di programma “orientato ad oggetti”: un videogioco Vincenzo Innocente - Corso breve OO

  15. Cliente Soldato Vincenzo Innocente - Corso breve OO

  16. FORTRANvsC/C++ • Sintassi F77 e C a confronto In C/ C++ non è necessario un particolare formato il codice PROGRAM TESTC esempio di programma ... END int main() {// esempio di programma ... return 0; // fine} spazi... Il C/ C++ è case sensitive Istruzioni separate da “;” INTEGER I INTEGER*4 J REAL X REAL*8 D int i;long j;float x;double d; Vincenzo Innocente - Corso breve OO

  17. FORTRANvsC/C++ • Controllo di flusso del programma DO I = 1, 10 . . . ENDDO IF (I.EQ.10 .AND. J.GT.4 .OR. X) THEN . . . ENDIF DO WHILE(X .NE. 5) . . . ENDDO for ( i = 1; i <= 10; i++ ) { . . .} if ( i == 10 && j > 4 || x ) { . . .} while( x != 5 ){ . . .} Vincenzo Innocente - Corso breve OO

  18. j ptr 12 24 Puntatori • Riferimento ad una locazione di memoria int main(){ int j = 12; return 0;} int *ptr = &j; #include <iostream.h> cout << *ptr << endl; j = 24; cout << *ptr << endl; cout << ptr << endl; 24 0x7b03a928 12 indirizzo di memoria Vincenzo Innocente - Corso breve OO

  19. j ptr 12 Puntatori • Puntatore nullo #include <iostream.h> int main(){ int j = 12; int *ptr = 0; cout << *ptr << endl; // crash ! return 0;} Segmentation violation (core dumped) Vincenzo Innocente - Corso breve OO

  20. ptr 12 Puntatori: allocazione dinamica • Riferimento ad una locazione di memoria #include <iostream.h> int main(){ int *ptr = new int; *ptr = 12; cout << *ptr << endl;delete ptr; return 0;} • Attenzione: • Non usare delete fa accumulare locazioni di memoria inutilizzate (memory leak) • Utilizzare puntatori prima del new o dopo il delete causa il crash del programma Vincenzo Innocente - Corso breve OO

  21. Classi astratte • Esempio classico: Shape • Tutti oggetti nella finestra hanno comportamenti comuni che possono essere considerati in astratto: • disegna, sposta, ingrandisci, etc. Vincenzo Innocente - Corso breve OO

  22. Nome della classe Circle.h Costruttore Distruttore Point2d: classe che rappresenta un punto in 2 dimensioni. Main.cc Circle.cc #include “Circle.h” void Circle::draw() const { const int numberOfPoints = 100; float x[numberOfPoints], y[numberOfPoints]; float phi = 0, deltaPhi = 2*M_PI/100; for ( int i = 0; i < numberOfPoints; ++i ) { x[i] = center_.x() + radius_ * cos( phi ); y[i] = center_.y() + radius_ * sin( phi ); phi += dphi; } polyline_draw(x, y, numberOfPoints ); } void Circle::moveAt( const Point2d& p ) { cancel(); center_ = p; draw(); } void Circle::scale( double s ) { cancel(); radius_ *= s; draw(); } Circle::Circle( Point2d c, double r ) : center_( c ), radius_( r ) { draw(); } Circle::~Circle() { cancel(); } #include “Circle.h” int main() { Circlec( Point2d(10, 10), 5 ); c.draw(); c.moveAt(Point2d(20, 30)); return 0; } Interfaccia Pubblica Metodi: operazioni sugli oggetti “Dati” privati (Attributi, membri) Punto e virgola! Cerchio class Circle { }; public: Circle(Point2d center, double radius); ~Circle(); void moveAt(const Point2d & p); void moveBy(const Point2d & p); void scale(double s); void rotate(double phi); void draw() const; void cancel() const; private: Point2d center_; double radius_; Vincenzo Innocente - Corso breve OO

  23. Square.h Square.cc class Square { public: Square(const Point2d&, const Point2d&); ~Square(); void moveAt( const Point2d& p ); void moveBy( const Point2d& p ); void scale( double s ); void rotate( double phi ); void draw() const; void cancel() const; private: Point2d center_; Vector2d centerToUpperCorner_; }; #include “Square.h” void Square::draw() const { float x[4], y[4]; Vector2d delta( centerToUpperCorner_ ); for ( int i = 0; i < 4; i++ ) { Point2d corner = center_ + delta; x[i] = corner.x(); y[i] = corner.y(); delta.rotate( M_PI_2 ); } polyline_draw(x, y, 4); } void Square::rotate( double phi ) { cancel(); centerToUpperCorner_.rotate( phi ); draw(); } Square::Square(const Point2d& lowerCorner, const Point2d& upperCorner ) : center_( median(lowerCorner, upperCorner) ), centerToUpperCorner_( upperCorner - center_ ){ draw(); } void Square::scale( double s ) { cancel(); centerToUpperCorner_ *= s; draw(); } Quadrato centerToUpperCorner_ upperCorner loweCorner Vincenzo Innocente - Corso breve OO

  24. Main.cc #include “Circle.h” #include “Square.h” int main() { Circle c1( Point2d(2.,3.), 4.23, ); Square r1( Point2d(2.,1.), Point2d(4.,3.) ); Circle * circles[ 10 ]; for ( int i = 0; i < 10; ++i ) { circles[ i ] = new Circle( Point2d(i,i), 2. ); } for ( int i = 0; i < 10; ++i ) circles[ i ]->draw(); return 0; } Codice Applicativo (Client) Costruisce un vettore di puntatori a cerchi, crea oggetti in memoria e salva i loro puntatori nel vettore. Itera sul vettore e invoca draw() per ogni elemento Come gestire cerchi e quadrati insieme? Vincenzo Innocente - Corso breve OO

  25. Polimorfismo Tutte le Shapes hanno la stessa interfaccia: draw, pick, move, fillColor..., ma ogni sottotipo diverso può avere la usa personale implementazione Vincenzo Innocente - Corso breve OO

  26. Shape.h Square.h Main.cc class Shape { public: Shape() { } virtual~Shape() { } virtual void moveAt( const Point2d& ) = 0; virtual void scale( double s ) = 0; virtual void rotate( double phi ) = 0; virtual void draw() const = 0; virtual void cancel() const = 0; }; #include “Shape.h” class Square: publicShape { // …. Il resto tutto uguale a prima }; #include “Circle.h” #include “Square.h” int main() { Shape * shapes[ 10 ]; int index = 0; for ( int i = 0; i < 10; i++ ) { Shape * s; s = new Circle( Point2d(i, i), 2.) ); shapes[ index ++ ] = s; s = new Square( Point2d(i, i), Point2d(i+1, i+2)) ); shapes[ index ++ ] = s; } for ( int i = 0; i < 10; i++ ) shapes[ i ]->draw(); return 0; } Interfaccia astratta Interfaccia di metodi puramente virtuali Vincenzo Innocente - Corso breve OO

  27. CenteredShape.h Square.h Class CenteredShape: public Shape { public: CenteredShape( Point2d c ) : center_( c ) { /*draw();*/ } ~Circle() { /*cancel();*/ } void moveAt( const Point2d& ); void moveBy( const Vector2d& ); virtual void scale( double ) = 0; virtual void rotate( double ) = 0; virtual void draw() const = 0; virtual void cancel() const = 0; protected: Point2d center_; }; #include “CenteredShape.hh” class Square : public CenteredShape { public: Square( Point2d lowerCorner, Point2d upperCorner ) : CenteredShape( median(lowerCorner, upperCorner) ), touc_(upperCorner - center_) { draw(); } ~Square() { cancel(); } virtual void scale( double s ) { cancel(); centerToUpperCorner_ *= s; draw(); } virtual void rotate( double phi ); virtual void draw() const; virtual void cancel() const; private: Vector2d touc_; }; Ereditarietà e riuso del codice Non si possono chiamare metodi virtuali in costruttori e distruttori (troppo presto, troppo tardi) Vincenzo Innocente - Corso breve OO

  28. Modello UML Vincenzo Innocente - Corso breve OO

  29. P.h Main.cc class P { public: P(int ix,int iy):x(ix),y(iy){} bool operator<(const P& b) const { return y<b.y ||( y==b.y && x<b.x ); } private: float x; float y; }; int main() { float a = min(3.,2.); int i = min(2,3); P p1(1.,2.), p2(3.,1.); P p3 = min(p1,p2); return 0; } Programmazione generica Funzioni Generiche template<class T> inline T min(const T& a, const T& b) { return a < b ? a:b; } “<” deve essere definito per “T” Usa min<float> Usa min<P> Vincenzo Innocente - Corso breve OO

  30. Vector3d.h Main.cc template <class T> class Vector3d { public: Vector3d(const T*a) { copy(a,a+3,&x[0]); } Vector3d<T>& operator+=(const Vector3d<T>& b) {x[0]+=b.x[0]; x[1]+=b.x[1]; x[2]+=b.x[2]; return *this;} private: T x[3]; }; #include “vector3d.h” int main() { Vector3d<float> a, b,c; c+=b+=a; Vector3d<complex> c1, c2; c2+=c1; return 0; } Programmazione generica Classi Generiche “copy” è una funzione generica di STL Ritorna se stesso per permettere la concatenazione di operatori Vincenzo Innocente - Corso breve OO

  31. La libreria standard: std (STL) • Contenitori generici: • vector, list, set, map, “string” • Iteratori • puntatori “intelligenti” nei contenitori generici • Funzioni generiche • copy, merge, find, sort, swap,… • agiscono su iteratori Vincenzo Innocente - Corso breve OO

  32. Main.cc #include <vector> int main() { vector<int> v; // creamo un vettore di interi vuoto cout << v.size() << endl; // stampa dimensione di v: zero for ( int i = 0; i != 10; ++i ) // un loop da 0 a 9 v.push_back( i ); // aggiungiamo un intero in coda a v cout << v.size() << endl; // stampa dimensione di v: 10 // creiamo un iteratore costante per un vettore di interi: // psi comporta come un “const int *” a tutti gli effetti vector<int>::const_iterator p; for ( p = v.begin(); p != v.end(); ++p ) // “itera dall’inizio alla fine di v” cout << (*p) << “ “; cout << endl; return 0; } Un semplice vettore Vincenzo Innocente - Corso breve OO

  33. begin() end() p p p p p p Un semplice vettore ... 0 1 2 9 Vincenzo Innocente - Corso breve OO

  34. Main.cc #include “Circle.h” #include “Square.h” #include <vector> int main() { vector<Shape *>vs; // un vettore di puntatori a Shapes for ( int i = 0; i != 10; ++i ) { // aggiungiamo un puntatore ad un nuovo cerchio vs.push_back(new Circle(Point2d(i, i), 2.)); // aggiungiamo un puntatore ad un nuovo quadrato vs.push_back(new Square(Point2d(i, i), Point2d(i + 1, i + 2))); } // iteratore: essenzialmente un puntatore a Shape* ossia un Shape** vector<Shape *>::const_iteratorp; for ( p = vs.begin(); p != vs.end(); ++p ) // loop sull’intero vettore (*p)->draw(); // disegniamo ogni Shape return 0; } Vettore di classe astratta Shape* Vincenzo Innocente - Corso breve OO

  35. Concetti Classici Riveduti • Relazioni tra oggetti • Decomposizione funzionale in una classe responsabilità dei metodi • Decomposizione funzionale tra classi responsabilità delle classi Vincenzo Innocente - Corso breve OO

  36. Superfici e traiettorie • Nel tracking spesso è necessario calcolare intersezioni tra curve (tracce) e superfici (elementi di detector) Vincenzo Innocente - Corso breve OO

  37. Line.h Helix.h Trajectory.h #include “Trajectory.h” class Line : public Trajectory { public: virtualPointposition(double s); virtualVectordirection(double s); public: Point origin_; Vector direction_; }; #include “Trajectory.h” class Helix : public Trajectory { public: virtualPointposition(double s); virtualVectordirection(double s);}; class Trajectory { public: virtualPointposition(double s) = 0; virtualVectordirection(double s) = 0; }; Superfici e traiettorie • Interfaccia delle diverse Trajectory Vincenzo Innocente - Corso breve OO

  38. Trajectory.cc Line.cc Helix.cc #include “Trajectory.h” // … vuoto ... #include “Line.h” Line::Line(const Point& o, constVector& d) : origin_( o ), direction_( d.unit() ) { } PointLine::position(double s) { return ( origin_ + s * direction_ ); } #include “Helix.h” Helix::Helix() { } PointHelix::position(double s) { // implementazione } Superfici e traiettorie • Implementazione Vincenzo Innocente - Corso breve OO

  39. Plane.h Surface.h Cylinder.h class Surface { public: virtualdistance(const Point& p) = 0; virtualderDist(const Point& p, const Vector& r) = 0; }; #include “Surface.h” class Plane : public Surface { public: virtualdistance(const Point& p); virtualderDist(const Point& p, const Vector& r); protected: Point origin_; Vector norm_; double dist_; }; #include “Surface.h” class Cylinder : public Surface { public: virtualdistance(const Point& p); virtualderDist(const Point& p, const Vector& r);}; Superfici e traiettorie • Interfaccia delle varie Surface distanza (con segno) di un punto dalla superficie Vincenzo Innocente - Corso breve OO

  40. Plane.cc Cylinder.cc Surface.cc #include “Plane.h” Plane::distance(const Point& p) { return ( _dist - ( (p - origin_) * direction_) ); } Plane::derDist(const Point& p, const Vector& r) { return - r * _direction; } #include “Cylinder.h” Cylinder::distance(const Point& p) { /* . . . */ } Cylinder::derDist(const Point& p, const Vector& r) { /* . . . */ } #include “Surface.h” // vuoto Superfici e traiettorie • Surface è una classe astratta Vincenzo Innocente - Corso breve OO

  41. Intersection.h class Surface; class Trajectory; class Intersection { public: Intersection(Surface* s, Trajectory* t) surface_(s), trajectory_(t) {} Pointintersect(double s1, double s2); protected: double sIntersect(double s1, double s2); Surface* surface_; Trajectory* trajectory_; }; Superfici e traiettorie • Interfaccia di Intersection forward class declaration Vincenzo Innocente - Corso breve OO

  42. Intersection.cc #include “Intersection.h” #include <math.h>#include “Surface.h”#include “Trajectory.h” const int maxIterations 20 const double sMax 1.e+6 const double accuracy1.e-3 double Intersection::sIntersect(double s1, double s2) { // algoritmo diNewton-Raphson double s = s1; double maxS = max(s1, s2); double minS = min(s1, s2); double d, delta; for( int j = 0; j < maxIterations; j++ ) { Point p = _trajectory->position( s ); d = surface_->distance( p ); delta = surface_->derDist( p, trajectory_->direction( s ) ); double ds = - d / delta; double test = s + ds; Superfici e traiettorie • Implementazione dell’algoritmo // controlla che test è tra s1 e s2 if( (s1 - test) * (test - s2) < 0.0 ) { if ( s1 < s2 ) s += abs( d ); else s -= abs( d ); if( s > maxS || s < minS ) return sMax; } else s = test; if( abs(d) < accuracy ) return s; } return sMax; } PointIntersection::intersect(double s1, double s2) { return trajectory_->position(sIntersect(s1, s2)); } Vincenzo Innocente - Corso breve OO

  43. Superfici e traiettorie • Intersection usa solo: • I metodi position e direction di un’oggetto Trajectory • I metodi distance e derDist di un oggetto Surface • E’ possibile aggiungere una nuova classe che modellizza una nuova Trajectory o una nuova Surface e Intersection continua a funzionare senza modificare una linea di codice! • E’ possibile rendere anche Intersection astratto... Vincenzo Innocente - Corso breve OO

  44. “Open/Closed principle” • Un buon codice deve essere • aperto ad estensioni • chiuso a modifiche • Modificare un codice funzionante può introdurre bachi… • L’Object Oriented, con il meccanismo delle classi virtuali, permette di applicare questo principio Vincenzo Innocente - Corso breve OO

  45. Disegno a oggetti:Modello di Hardware DAQ Costruiamo un modello del Hardware per un sistema di acquisizione • “Use Cases”: • gestione delle parti (dove sono, a chi appartengono) • simulazione (potenza dissipata, spazio occupato) • controllo on-line (on/off, temperatura, voltaggio) • DAQ (questi dati da dove vengono?) • calibrazione (piedistalli, guadagni, fattori di conversione) Vincenzo Innocente - Corso breve OO

  46. Chi sono i giocatori? • I componenti Hardware: Racks, crates, moduli di vario tipo e foggia • “Utenti” (persone, displays, interfacce) conviene avere un “corrispondente” nel modello Primi candidati a classi e oggetti Vincenzo Innocente - Corso breve OO

  47. Un primo modello Vincenzo Innocente - Corso breve OO

  48. Calcolo della potenza in un rack Vincenzo Innocente - Corso breve OO

  49. La base di un modello composto Vincenzo Innocente - Corso breve OO

  50. DaqLeaf.h DaqComponent.h #include “DaqComponent.h” class DaqLeaf: public DaqComponent { public: explicit DaqLeaf( float ip = 0 ): power_(ip) {} virtual float power() const { return power_;} } protected: float power_; }; class DaqComposite; // forward declaration class DaqComponent { public: DaqComponent() : parent_(0) {} virtual float power() const = 0; protected: DaqComposite * parent_; }; Codice del modello composto Vincenzo Innocente - Corso breve OO

More Related