appunti3s:polimorfismo
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
appunti3s:polimorfismo [2013/06/17 21:07] – external edit 127.0.0.1 | appunti3s:polimorfismo [2020/06/08 22:19] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Polimorfismo ====== | ||
+ | Nel caso in cui l'// | ||
+ | ===== Usando Puntatori a... ===== | ||
+ | |||
+ | L' | ||
+ | * un oggetto di tipo classe Derivata deve essere (allo stesso tempo) anche del tipo Base | ||
+ | * cioè che i puntatori (o reference) che uso per oggetti della Base possano puntare anche oggetti della Derivata | ||
+ | |||
+ | Perché questo è possibile, mentre non è possibile l' | ||
+ | |||
+ | Nel seguente esempio la classe Derivata è " | ||
+ | < | ||
+ | class Base | ||
+ | {....}; | ||
+ | |||
+ | class Derivata : public Base | ||
+ | {....}; | ||
+ | </ | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Si può creare //pBase// e //pDeriv//, rispettivamente, | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Se si immagina di scambiare il contenuto delle aree puntate dai puntatori, ad una prima impressione potrebbe sembrare che lo scambio sarebbe corretto solo se l'area puntata (tratteggiata) fosse abbastanza grande per contenere il nuovo oggetto. Invece le cose stanno esattamente al contrario... | ||
+ | - Per utilizzare il puntatore per la classe Base //pBase// su un oggetto della Derivata, si devono e si possono " | ||
+ | - Per utilizzare il puntatore per la classe Derivata | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Poiché, nella relazione di ereditarietà, | ||
+ | Come in questo esempio: | ||
+ | < | ||
+ | void Base::fun() | ||
+ | { | ||
+ | //... | ||
+ | } | ||
+ | |||
+ | void Derivata:: | ||
+ | { | ||
+ | //... | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | Base* pBase = new Base(); | ||
+ | | ||
+ | pBase = pDerivata; | ||
+ | | ||
+ | // il puntatore è di tipo Base*, l' | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Early binding ===== | ||
+ | Questo tipo di ambiguità, in C++, viene risolta al momento della compilazione, | ||
+ | Questa soluzione è più efficiente e si chiama //early binding// (o anche static binding). | ||
+ | |||
+ | ===== Late binding ===== | ||
+ | Viceversa, se dichiaro la funzione // | ||
+ | < | ||
+ | virtual void Base::fun() | ||
+ | { | ||
+ | //... | ||
+ | } | ||
+ | |||
+ | virtual void Derivata:: | ||
+ | { | ||
+ | //... | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | Base* pBase = new Base(); | ||
+ | | ||
+ | pBase = pDerivata; | ||
+ | | ||
+ | // la funzione BASE::fun() è virtual quindi | ||
+ | // ora non conta il tipo di puntatore ma l' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | È Il tipo di oggetto che invoca la funzione //virtual// a determinare quale versione di tale funzione deve essere usata. | ||
+ | Quest' | ||
+ | |||
+ | Quando progetto una classe, se voglio che nelle chiamate di funzione comandi il tipo di puntatore, invece del dell' | ||
+ | |||
+ | L' | ||
+ | * Le funzioni " | ||
+ | * I costruttori NON possono essere // | ||
+ | * La funzione membro //virtual// della classe Derivata può richiamare quella della Base usando l' | ||
+ | * Le funzioni membro // | ||
+ | |||
+ | |||
+ | ====Classe astratta==== | ||
+ | |||
+ | Vedere anche relazione di [[appunti3s: | ||
+ | |||
+ | Questo tipo di classe si usa quando la classe non deve rappresentare concetti concreti e/o quando __non__ si devono realizzare mai oggetti di questo tipo. Grazie all' | ||
+ | |||
+ | * Nella //classe astratta// deve esserci almeno una funzione membro //virtuale pura//. < | ||
+ | * Nella //classe astratta// non viene // | ||
+ | * Una classe Derivata da una //classe Base astratta//, è a sua volta //classe astratta//, se la funzione //virtuale pura// __non__ viene implementata nella Derivata. |
appunti3s/polimorfismo.txt · Last modified: 2020/06/08 22:19 by 127.0.0.1