polimorfismo permette riutilizzo del codice, consentendo oggetti di tipi correlati ad essere trattati allo stesso.
consideri che potrebbe essere necessario decine di sottoclassi che si comportano in modo diverso:
struct Shape1: public Shape { /* .. */ }; // triangle
struct Shape2: public Shape { /* .. */ }; // rectangle
// ...
struct ShapeN: public Shape { /* .. */ }; // projection of rhombic triacontahedron
consideri che potrebbe essere necessario per elaborare oggetti appuntiti da una serie di Shape
puntatori.
Con polimorfismo, è necessario un singolo vettore, e un singolo ciclo con funzione virtuale chiamate:
std::vector<Shape*> v = get_shape_vector();
for(Shape* s : v)
s->draw();
Senza polimorfismo, si avrebbe il gestore di un array separato per ciascun tipo ed elaborarli separatamente:
std::vector<Shape1> v1 = get_shape1_vector();
std::vector<Shape2> v2 = get_shape2_vector();
// ...
std::vector<ShapeN> vN = get_shapeN_vector();
for(Shape1& s : v1)
s.draw();
for(Shape2& s : v2)
s.draw();
// ...
for(ShapeN& s : vN)
s.draw();
Le 3 righe di codice che utilizzano il polimorfismo sono molto più facili da gestire rispetto alle linee di codice 3 * N che non utilizzano il polimorfismo.
Considerare che potrebbe essere necessario modificare il processo. Forse vuoi aggiungere una chiamata di funzione prima di disegnare. Questo è semplice quando si ha il polimorfismo dalla vostra parte:
void pre_draw(Shape*);
for(Shape* s : v) {
pre_draw(s);
s->draw();
}
Senza il polimorfismo, è necessario definire le decine di funzioni e modificare ogni della dozzina loop:
void pre_draw1(Shape1&);
void pre_draw2(Shape2&);
// ...
void pre_drawN(ShapeN&);
for(Shape1& s : v1) {
pre_draw1(s);
s.draw();
}
for(Shape2& s : v1) {
pre_draw2(s);
s.draw();
}
// ...
for(ShapeN& s : v1) {
pre_drawN(s);
s.draw();
}
Si consideri che è possibile aggiungere forme più tardi . Con il polimorfismo, è sufficiente definire il nuovo tipo e la funzione virtuale. È possibile semplicemente aggiungere puntatori ad esso nell'array e verranno elaborati proprio come gli oggetti di ogni altro tipo compatibile.
struct ShapeN1: public Shape { /* .. */ }; // yet another shape
Senza polimorfismo, oltre a definire il nuovo tipo, è necessario creare un nuovo array per esso. E avresti bisogno di creare una nuova funzione pre_draw
. E avresti bisogno di aggiungere un nuovo ciclo per elaborarli.
void pre_drawN1(ShapeN1&);
// ...
std::vector<ShapeN1> vN1 = get_shapeN1_vector();
// ...
for(ShapeN1& s : vN1) {
pre_drawN1(s);
s.draw();
}
In realtà, si avrebbe bisogno di passare attraverso la vostra intera base di codice per i luoghi in cui ogni di tipo di forma viene elaborato e aggiungere il codice per il nuovo tipo lì.
Ora, N potrebbe essere piccolo o grande. Maggiore è N, più il polimorfismo di ripetizione evita. Ma, non importa quante poche sottoclassi hai, non dover guardare attraverso l'intera base di codice quando ne aggiungi una nuova è un grande vantaggio.
Non c'è bisogno di un nuovo puntatore nel tuo caso. Ma questo non è correlato a "qual è il bisogno (per) il polimorfismo ..." – juanchopanza
Il punto delle funzioni virtuali è così che possiamo definire il comportamento in fase di esecuzione e consentire l'utilizzo dinamico degli oggetti. Il polimorfismo è il nome dato a questo. – Lawrence
Ad esempio, potresti voler creare una raccolta di forme. Si consideri '' 'std :: vector' ''. Può contenere forme diverse ma puoi fare cose comuni a tutte loro. –
isapego