Polimorfizm umożliwia ponowne wykorzystanie kodu, umożliwiając obiektów powiązanych rodzajów należy traktować tak samo.
Uważają, że może trzeba dziesiątki podklasy, które zachowują się inaczej:
struct Shape1: public Shape { /* .. */ }; // triangle
struct Shape2: public Shape { /* .. */ }; // rectangle
// ...
struct ShapeN: public Shape { /* .. */ }; // projection of rhombic triacontahedron
Uważają, że może trzeba przetwarzania obiektów wskazanych przez tablicę Shape
wskaźników.
z polimorfizmem, trzeba jeden wektor, a pojedyncza pętla z funkcją wirtualną nazywa:
std::vector<Shape*> v = get_shape_vector();
for(Shape* s : v)
s->draw();
Bez polimorfizmu, trzeba zarządzać oddzielną tablicę dla każdego typu i przetwarzać je oddzielnie:
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();
Trzy linie kodu korzystające z polimorfizmu są łatwiejsze do utrzymania niż 3 * N wiersze kodu, które nie używają polimorfizmu.
Należy wziąć pod uwagę, że konieczne może być zmodyfikowanie procesu. Być może chcesz dodać wywołanie funkcji przed rysowaniem. To jest proste, gdy masz polimorfizmu na swojej stronie:
void pre_draw(Shape*);
for(Shape* s : v) {
pre_draw(s);
s->draw();
}
Bez polimorfizmu, trzeba zdefiniować dziesiątki funkcji i modyfikować każdy z kilkunastu pętle:
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();
}
Uważają, że można dodawać kształty później . W przypadku polimorfizmu wystarczy zdefiniować nowy typ i funkcję wirtualną. Możesz po prostu dodać do niej wskaźniki i będą one przetwarzane tak jak obiekty każdego innego kompatybilnego typu.
struct ShapeN1: public Shape { /* .. */ }; // yet another shape
Bez definiowania polimorfizmów, oprócz definiowania nowego typu, trzeba byłoby utworzyć dla niego nową tablicę. I musisz utworzyć nową funkcję pre_draw
. I musisz dodać nową pętlę, aby je przetworzyć.
void pre_drawN1(ShapeN1&);
// ...
std::vector<ShapeN1> vN1 = get_shapeN1_vector();
// ...
for(ShapeN1& s : vN1) {
pre_drawN1(s);
s.draw();
}
W rzeczywistości, trzeba by przejść przez cały kod bazowy dla miejsc, w których każdy z rodzaju kształt jest przetwarzany i dodać kod dla nowego typu tam.
Teraz N może być mały lub wielki. Im większe jest N, tym bardziej unika się polimorfizmu powtórzeń. Ale bez względu na to, jak mało masz podklas, nie musisz przeglądać całej bazy kodu, kiedy dodajesz nową, jest wielkim dobrodziejstwem.
Nie ma potrzeby dodawania nowego wskaźnika w twoim przypadku. Ale to nie ma związku z "czym jest potrzeba (dla) polimorfizmu ...". – juanchopanza
Punkt funkcji wirtualnych polega na tym, że możemy zdefiniować zachowanie w środowisku wykonawczym i umożliwić dynamiczne wykorzystanie obiektów. Polimorfizm to nazwa nadana temu. – Lawrence
Na przykład możesz utworzyć kolekcję kształtów. Rozważmy '' 'std :: vector' ''. Może zawierać różne kształty, ale można zrobić wspólne rzeczy dla wszystkich z nich. –
isapego