Vincenzo Innocente1 Introduction to Object-Oriented Programming in C++ Vincenzo Innocente CERN, Geneva, Switzerland.

Slides:



Advertisements
Presentazioni simili
Programmazione ad oggetti
Advertisements

1 La Standard Template Library vettori, liste, mappe, …. find, replace, reverse, sort, …. puntatori intelligenti La libreria standard STL e una libreria.
Astrazioni Polimorfe e Tipi Generici. 2 Polimorfismo Dal Greco molte forme Una variabile polimorfa può riferirsi a oggetti di classi diverse Un metodo.
Introduzione al C++ e alla programmazione ad oggetti Corso Specialistico CNTC Bologna, febbraio 2001 Andrea Dell’Acqua e Claudio Grandi.
Unified Modeling Language
Programmazione object oriented in C++
Differenze nei vari linguaggi di Elisa Trifirò e Barbara Tacchino
Le gerarchie di tipi.
Liste Ordinate 3 Maggio Ultima Lezione Abbiamo visto i tipi di dato astratti IntList e StringList Realizzano liste di interi e di stringhe Realizzati.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
Differenze tra C e C++ Commenti: Adesso puoi inserire dei commenti tra // e la fine della linea. Usare le librerie C: In C++ puoi anche chiamare una funzione.
Fondamenti di Informatica Prof. Cantone
Concetti di base: header file, funzione main(),set caratteri C++, token, operatori, espressioni etc. Flusso di controllo, cicli, costrutti.
Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.
Distributed Object Computing
Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI
1 Programmazione ad oggetti in Java E.Mumolo, DEEI
E.Mumolo. DEEI Introduzione alla programmazione ad oggetti in C++ Object Oriented Programming, OOP E.Mumolo. DEEI
Costruzione di Interfacce Lezione 12 C++STL
Introduzione al linguaggio C++ 5 lezioni
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Introduzione a JAVA Anno Accademico 2009/2010.
Introduzione al linguaggio Java
1 Introduzione ai design pattern. 2 Cosa sono i design pattern I problemi incontrati nello sviluppare grossi progetti software sono spesso ricorrenti.
Programmazione orientata agli oggetti nel calcolo scientifico
Il linguaggio UML Luca Lista. Metodi Object Oriented –Booch Method by Grady Booch –OMT by Jim Rumbaugh –Objectory (Use Cases) by Ivar Jacobson –CRC by.
L.Lista Design P atterns Luca Lista. L.Lista Design Patterns Elementi di software OO riutilizzabile Piccoli insiemi di classi che collaborano implementando.
Overriding.
Gestione dei Progetti Software 2 (a.a. 2004/05) - Lezione 3 1 JAVA e Internet: il World Wide Web Internet: milioni di computer collegati fra di loro attraverso.
CAPITOLO 4 LINGUAGGIO JAVA: COSTRUTTI DI BASE. ALFABETO Java adotta la codifica standard Unicode della società Unicode, Inc. (ftp://ftp.unicode.org) definito.
© CEFRIEL Ricettario dei principali pattern GoF Docente: Gabriele Lombardi
1 laboratorio di calcolo II AA 2003/04 nona settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza tel. ( )
1 laboratorio di calcolo II AA 2003/04 quinta settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza tel. ( )
1 laboratorio di calcolo II AA 2003/04 quarta settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza tel. ( )
Design Pattern Observer INGEGNERIA DEL SOFTWARE Nicola Ferrari.
1 Ereditarietà Una classe può essere derivata da una classe esistente usando la sintassi: public, protected e private specificano il tipo di accesso ai.
Le classi Definizione di classe Attributi e metodi di una classe Costruttori e distruttori Private e public Funzioni friend Il puntatore this.
Struct, enum, Puntatori e Array dinamici
Java base IV: Java e la programmazione O.O.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Introduzione alla programmazione Object Oriented
Introduzione al C++ Introduzione al linguaggio C++
Enumerazioni e Classi 1. Enumerazioni Permettono di definire nuovi tipi che consistono in un insieme di valori costanti (ognuno con un nome) – Migliorano.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
Fondamenti di Programmazione Prof.ssa Elisa Tiezzi
I nomi in Java F. Bombi 18 novembre novembre 2003.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
CORSO DI PROGRAMMAZIONE II Lezione 22
Programmazione ad oggetti
Lezione 1 Panoramica sui paradigmi di programmazione
Oggetti in C# Lezione 2 Metodi e Static Oggetti in C# - Lezione 2.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 7 Tipi di dato e strutture dati Specifica e realizzazione di strutture informative come classi.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Alberi.
L.Lista, V. Innocente Design P atterns Luca Lista, Vincenzo Innocente.
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Strutture Dati.
Vincenzo Innocente - Corso breve OO 1 Introduzione ai linguaggi compilati orientati ad oggetti Alessandra Doria, Napoli Vincenzo Innocente, CERN Luca Lista,
Esercitazione sull’ ordinamento 20 maggio 2003
LIP: 4 Maggio 2007 Interfacce. Cos’e’ una Interfaccia una interfaccia e’ un particolare tipo di classe contiene solo la specifica non ha implementazione.
Corso di Algoritmi e Strutture Dati con Laboratorio Richiami di Java – parte II.
Corso di Algoritmi e Strutture Dati con Laboratorio A.A. 2015/16 Oltre le classi.
Introduzione al C++ e alla programmazione ad oggetti.
Introduzione all’Ereditarietà Pietro Palladino. Richiami UML Classe: descrizione di un insieme di oggetti software con caratteristiche simili Definisce.
Due slides sui Design Patterns Luciano Pandola INFN-LNGS Corso INFN su C++, ROOT e Geant4.
Introduzione alle Classi e agli Oggetti in Java 1.
Tecniche di Problem-Solving
Transcript della presentazione:

Vincenzo Innocente1 Introduction to Object-Oriented Programming in C++ Vincenzo Innocente CERN, Geneva, Switzerland

Vincenzo Innocente2 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 Innocente3 C++ /Object Oriented Riduce la dipendenza del codice di alto livello dalla rappresentazione dei dati Permette il riutilizzo del codice di alto livello Nasconde i dettagli di implementazione

Vincenzo Innocente4 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 Innocente5 Concetti base dell’OO Classi ed oggetti Incapsulamento Relazione di ereditarietà Polimorfismo Programmazione Generica ( C++ )

Vincenzo Innocente x7b03a928 Puntatori Riferimento ad una locazione di memoria j 12 ptr int main() { int j = 12; return 0; } int *ptr = &j; #include cout << *ptr << endl; j = 24; cout << *ptr << endl; cout << ptr << endl; indirizzo di memoria 24

Vincenzo Innocente7 Puntatori Puntatore nullo #include int main() { int j = 12; int *ptr = 0; cout << *ptr << endl; // crash ! return 0; } Segmentation violation (core dumped) j 12 ptr

Vincenzo Innocente8 Puntatori: allocazione dinamica Riferimento ad una locazione di memoria #include int main() { int *ptr = new int; *ptr = 12; cout << *ptr << endl; delete ptr; return 0; } 12 ptr 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 Innocente9 Classi e Oggetti Un esempio di programma “orientato ad oggetti”: un videogioco

Vincenzo Innocente10 SoldatoSoldatoClienteCliente

Vincenzo Innocente11 Class Vector An example: un tri-dimentional vector With respect to a structure, a class contains functions beside data class Vector { public: Vector(double x, double y, double z); Vector(Vector& v); double x(); double y(); double z(); double r(); double phi(); double theta(); protected: double _x, _y, _z; }; Vector.h #include “Vector.h” Vector::Vector(double x, double y, double z) : _x(x), _y(y), _z(z) {} Vector::Vector(Vector& v) : _x(v.x()), _y(v.y()), _z(v.z()) {} double Vector::x() { return _x; } double Vector::r() { return sqrt(_x*_x + _y*_y + _z*_z); } Vector.cc data functions or methods constructor copy constructor

Vincenzo Innocente12 Class Vector #include #include “Vector.h” int main() { Vector v(1, 1, 0); cout << “ v = (“ << v.x() << “,” << v.y() << “,” << v.z() << “)” << endl; cout << “ r = “ << v.r(); cout << “ theta = “ << v.theta() << endl; } main.cc How to use Vector : v = (1, 1, 0) r = theta = Output: invoke the constructor

Vincenzo Innocente13 Class Vector #include #include “Vector.h” int main() { Vector v(1, 1, 0); cout << “ V = (“ << v._x << “,” // << v._y << “,” // does not << v._z << “)” << endl; // compile ! cout << “ r = “ << v.r(); cout << “ theta = “ << v.theta() << endl; } main.cc Data access protection:

Vincenzo Innocente14 #include “Vector.h” Vector::Vector(double x, double y, double z) : _x(x), _y(y), _z(z) {} double Vector::x() const { return _x; } double Vector::r() const { return sqrt(x*x + y*y + z*z); } Interface and implementation Protected data are not accessible outside the class class Vector { public: Vector(double x, double y, double z); double x() const; double y() const; double z() const; double r() const; double phi() const; double theta() const; protected: double _x, _y, _z; }; Vector.hh Vector.cc const

Vincenzo Innocente15 Interface and implementation The internal structure of the data ( _x, _y, _z ) that represent the objects of the class Vector are hidden ( protected ) to the clients of the class. The clients do not depend on the internal structure of the data (as it was the case for clients of FORTRAN common block) If the internal structure changes (es.: _r, _theta, _phi ), the code using Vector does not have to be modified.

Vincenzo Innocente16 Operators It is possible to redefine +, -, *, [], ++, ==,... class Vector { public: Vector(double x, double y, double z); double x() const; double y() const; double z() const; double r() const; double phi() const; double theta() const; Vector operator+(const Vector& v) const; Vector operator-(const Vector& v) const; protected: double _x, _y, _z; }; Vector.hh Vector Vector::operator+(const Vector& v) const { return Vector(_x + v._x, _y + v._y, _z + v._z); } Vector Vector::operator-(const Vector& v) const { return Vector(_x - v._x, _y - v._y, _z - v._z); } Vector.cc

Vincenzo Innocente17 Operators Example: #include #include “Vector.h” int main() { Vector v1(1, 0, 0), v2(0, 1, 0); Vector v; v = v1 + v2; cout << “ v = “ << v << endl; cout << “ r = “ << v.r(); cout << “ theta = “ << v.theta() << endl; } main.cc v = (1, 1, 0) r = theta = Output: redefinition of <<

Vincenzo Innocente18 Operators Example: #include #include “Vector.h” #include “Matrix.h” // matrix 3x3 int main() { Vector v1(1, 1, 0); double phi = M_PI/3; double c = cos(phi), s = sin(phi); Matrix m(1, 0, 0, 0, c, s, 0, -s, c); Vector u = m * v; } main.cc 

Vincenzo Innocente19 Operator overloading It is possible to define functions with the same name but different arguments class Vector { public:... Vector operator*(double s) const; double operator*(const Vector& v) const; protected: double _x, _y, _z; }; Vector.hh Vector Vector::operator*(double s) const { return Vector(_x *s, _y *s, _z *s); } double Vector::operator*(const Vector& v) const { return (_x * v._x + _y * v._y + _z * v._z); } Vector.cc

Vincenzo Innocente20 Static Functions and data Some functions can be common to the whole class class Particle { public: Particle(int code, double mass, int charge); int code() const { return _code; }; double mass() { return _mass; }; int charge() { return _charge; }; static int numberOfParticles(); protected: double _mass; int _code, _charge; static int _n; }; Particle.h #include “Particle.h” int Particle::_n = 0; Particle::Particle(int code, double mass, int charge) : _code(code), _mass(mass), _charge(charge) { _n ++; } int Particle::numberOfParticles() { return _n; } Particle.cc

Vincenzo Innocente21 Classi astratte Esempio classico: Shape Tutti oggetti nella finestra hanno comportamenti comuni che possono essere considerati in astratto:Tutti oggetti nella finestra hanno comportamenti comuni che possono essere considerati in astratto: –disegna, sposta, ingrandisci, etc.

Vincenzo Innocente22 Ereditarietà e riuso del codice 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_; }; CenteredShape.h Non si possono chiamare metodi virtuali in costruttori e distruttori (troppo presto, troppo tardi) #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_; }; Square.h

Vincenzo Innocente23 Quadrato 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_; }; Square.h #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(); } Square.cc upperCorner loweCorner centerToUpperCorner _

Vincenzo Innocente24 Circle.h Cerchio Costruttore Distrutt ore Nome della classe Punto e virgola! Point2d : classe che rappresenta un punto in 2 dimensioni. 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; “Dati” privati (Attributi, membri) class Circle { }; private: Point2d center_; double radius_; Interfaccia Pubblica Metodi: operazioni sugli oggetti # 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(); } Circle.cc #include “Circle.h” int main() { Circle c( Point2d(10, 10), 5 ); c.draw(); c.moveAt(Point2d(20, 30)); return 0; } Main.cc

Vincenzo Innocente25 Codice Applicativo (Client) #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; } Main.cc Come gestire cerchi e quadrati insieme? 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

Vincenzo Innocente26 Programmazione generica Funzioni Generiche template inline T min(const T& a, const T& b) { return a < b ? a:b; } 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; }; P.h 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; } Main.cc Usa min Usa min “<” deve essere definito per “T”

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

Vincenzo Innocente28 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 Innocente29 Un semplice vettore #include int main() { vector 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: // p si comporta come un “const int *” a tutti gli effetti vector ::const_iterator p; for ( p = v.begin(); p != v.end(); ++p ) // “itera dall’inizio alla fine di v” cout << (*p) << “ “; cout << endl; return 0; } Main.cc

Vincenzo Innocente30 Un semplice vettore begin() end() end() p p pp p p

Vincenzo Innocente31 Vettore di classe astratta Shape* #include “Circle.h” #include “Square.h” #include int main() { vector 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 ::const_iterator p; for ( p = vs.begin(); p != vs.end(); ++p ) // loop sull’intero vettore (*p)->draw(); // disegniamo ogni Shape return 0; } Main.cc

Vincenzo Innocente32 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; }; Shape.h Interfaccia astratta Interfaccia di metodi puramente virtuali #include “Shape.h” class Square : public Shape { // …. Il resto tutto uguale a prima }; Square.h #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; } Main.cc

Vincenzo Innocente33 Superfici e traiettorie Nel tracking spesso è necessario calcolare intersezioni tra curve (tracce) e superfici (elementi di detector)

Vincenzo Innocente34 Superfici e traiettorie Interfaccia delle diverse Trajectory #include “Trajectory.h” class Line : public Trajectory { public: virtual Point position(double s); virtual Vector direction(double s); public: Point origin_; Vector direction_; }; Line.h #include “Trajectory.h” class Helix : public Trajectory { public: virtual Point position(double s); virtual Vector direction(double s); }; Helix.h class Trajectory { public: virtual Point position(double s) = 0; virtual Vector direction(double s) = 0; }; Trajectory.h

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

Vincenzo Innocente36 #include “Surface.h” class Plane : public Surface { public: virtual distance(const Point& p); virtual derDist(const Point& p, const Vector& r); protected: Point origin_; Vector norm_; double dist_; }; Plane.h class Surface { public: virtual distance(const Point& p) = 0; virtual derDist(const Point& p, const Vector& r) = 0; }; Surface.h Superfici e traiettorie Interfaccia delle varie Surface #include “Surface.h” class Cylinder : public Surface { public: virtual distance(const Point& p); virtual derDist(const Point& p, const Vector& r); }; Cylinder.h distanza (con segno) di un punto dalla superficie

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

Vincenzo Innocente38 Superfici e traiettorie Interfaccia di Intersection class Surface; class Trajectory; class Intersection { public: Intersection(Surface* s, Trajectory* t) surface_(s), trajectory_(t) {} Point intersect(double s1, double s2); protected: double sIntersect(double s1, double s2); Surface* surface_; Trajectory* trajectory_; }; Intersection.h forward class declaration

Vincenzo Innocente39 Superfici e traiettorie Implementazion e dell’algoritmo #include “Intersection.h” #include #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 di Newton-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; Intersection.cc // 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; } Point Intersection::intersect(double s1, double s2) { return trajectory_- >position(sIntersect(s1, s2)); }

Vincenzo Innocente40 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 I ntersection continua a funzionare senza modificare una linea di codice! E’ possibile rendere anche Intersection astratto...

Vincenzo Innocente41 “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 Innocente42 Conclusioni La programmazione C++ Object Oriented può aiutare a ridurre le dipendenze all’interno del codice e quindi lo sviluppo del programma... … ma va utilizzato in maniera adeguata, disegnando il codice prima di implementarlo è facile scrivere un codice C++ traslitterando un codice F77, ma questo non produce grandi miglioramenti

Vincenzo Innocente43 Unified Modeling Language Class Diagrams Sequence and Collaboration Diagrams Use Case Diagrams State Diagrams

Vincenzo Innocente44 UML Model of “Shape”

Vincenzo Innocente45 Class Diagram

Vincenzo Innocente46 Class Diagram

Vincenzo Innocente47 Object Sequence Diagram

Vincenzo Innocente48 Object Collaboration Diagram

Vincenzo Innocente49 Design Patterns “Elementi di software OO riutilizzabile” Piccoli insiemi di classi che collaborano implementando dei comportamenti tipici –Creational patterns –Structural patterns –Behavioral patterns Alcuni pattern classici stanno diventanto obsoleti grazie al supporto dei Template E. Gamma et al., Design Patterns

Vincenzo Innocente50 Factory AbstractProduct ConcreteProduct1 ConcreteProduct2 Factory createProduct1 () : AbstractProduct createProduct2 () : AbstractProduct Client I client possono richiedere la creazione di un prodotto senza dipendervi. La Factory dipende dai prodotti concreti, mentre i client dipendono solo AbstractPro duct.

Vincenzo Innocente51 Singleton Il Singleton pattern piò essere usato ogni volta che una classe deve essere instanziata una sola volta, e viene usata da diversi oggetti. Per evitare istanziazione accidentale, il constructor deve essere privato. Più istanze, ma in numero ben determinato, possono esistere (multiton) Siccome vengono usate funzioni statiche, l’ereditarietà non può essere applicata. Singleton _instance : Singleton instance () : Singleton specificService () if (_instance==0) _instance = new Singleton(); return _instance; user_code() { Singleton::instance()- >specificService(...); } user_code() { Singleton::instance()- >specificService(...); }

Vincenzo Innocente52 Template Singleton Un Template Singleton può essere specializzato usando la classe stessa come argomento del template. Se V ha un constructor privato, Singleton deve essere friend di V (non tutti i compilatori lo supportano…). if (_instance==0) _instance = new T(); return _instance; Singleton _instance : T instance () : T V V( ) specificService( ) Singleton{V} T class V : public Singleton { public: specificService(...); private: V(); friend class Singleton ; }; user_code() { V::instance() ->specificService(...); } class V : public Singleton { public: specificService(...); private: V(); friend class Singleton ; }; user_code() { V::instance() ->specificService(...); }

Vincenzo Innocente53 Proxy Una richiesta da un client a un server, può essere mediata dal Proxy, che può compiere anche altre operazioni (I/O, caching, etc.) Subject request( ) RealSubject request( ) Proxy _subject : RealSubject request( ) 1 1 Client _subject... _subject->request();...

Vincenzo Innocente54 Composite Leaf operation( ) Component operation( ) Composite operation( ) 1..* Client for c in all _children c->operation(); _children Il client può trattare componenti e compositi usando la stessa interfaccia. La composizione può essere recursiva. Esempio: programmi di grafica vettoriale

Vincenzo Innocente55 Composite Shape Cerchio, Rettangolo,... draw( ) Shape draw( ) Gruppo draw( ) 1..* Client for c in all _children c->draw(); _children Nel nostro esempio di grafica con Shapes un gruppo può essere considerato un composito e le varie classi concrete sono le leaves.

Vincenzo Innocente56 Strategy Il pattern Strategy permette di scegliere l’algoritmo da eseguire a run-time. Nuovi algoritmi possono essere introdotti senza modificare i client. ConcreteStrategyA doAlgorithm( ) ConcreteStrategyB doAlgorithm( ) ConcreteStrategyC doAlgorithm( ) Client Strategy doAlgorithm( ) {... Strategy* s; s->doAlgorithm();... }

Vincenzo Innocente57 Observer Lo stato dell’ Observer dipende dallo stato del Subject. Il Subject notifica a tutti gli Observer registrati che il suo stato è cambiato. Observer update( ) Subject _observers : Observer attach (Observer) notify () 0..* for all o in _ observables o->update(); _observers return _status; _status = _subject->status(); ConcreteSubject _status : Status status( ) ConcreteObserver _status : Status _subject. ConcreteSubject update( ) _subject

Vincenzo Innocente58 Visitor visit1 (ConcreteElement1) visit2 (ConcreteElement2) ConcreteVisitor1 visit1 (ConcreteElement1) visit2 (ConcreteElement2) ConcreteVisitor2 visit1 (ConcreteElement1) visit2 (ConcreteElement2) Element accept (Visitor) ConcreteElement1 accept (Visitor v) ConcreteElement2 accept (Visitor v) Client v->visit1(this) v->visit2(this) Permette di aggiungere nuove operazioni a Element senza modificarne l’interfaccia. Per aggiungere nuovi ConcreteElement, bisogna modificare tutti i Visitor s.