Σε αυτό το σεμινάριο, θα μάθουμε για τον πολυμορφισμό στο C ++ με τη βοήθεια παραδειγμάτων.
Ο πολυμορφισμός είναι μια σημαντική έννοια του αντικειμενοστρεφούς προγραμματισμού. Σημαίνει απλά περισσότερες από μία φόρμες. Δηλαδή, η ίδια οντότητα (λειτουργία ή χειριστής) συμπεριφέρεται διαφορετικά σε διαφορετικά σενάρια. Για παράδειγμα,
Ο +
χειριστής στο C ++ χρησιμοποιείται για την εκτέλεση δύο συγκεκριμένων λειτουργιών. Όταν χρησιμοποιείται με αριθμούς (ακέραιοι και αριθμοί κινητής υποδιαστολής), εκτελεί προσθήκη.
int a = 5; int b = 6; int sum = a + b; // sum = 11
Και όταν χρησιμοποιούμε τον +
τελεστή με συμβολοσειρές, εκτελεί συνένωση συμβολοσειρών. Για παράδειγμα,
string firstName = "abc "; string lastName = "xyz"; // name = "abc xyz" string name = firstName + lastName;
Μπορούμε να εφαρμόσουμε τον πολυμορφισμό στο C ++ χρησιμοποιώντας τους ακόλουθους τρόπους:
- Υπερφόρτωση λειτουργίας
- Υπερφόρτωση χειριστή
- Παράκαμψη λειτουργίας
- Εικονικές λειτουργίες
Υπερφόρτωση λειτουργίας C ++
Στο C ++, μπορούμε να χρησιμοποιήσουμε δύο συναρτήσεις με το ίδιο όνομα, εάν έχουν διαφορετικές παραμέτρους (είτε τύπους είτε αριθμός ορισμάτων).
Και, ανάλογα με τον αριθμό / τύπο ορισμάτων, καλούνται διαφορετικές συναρτήσεις. Για παράδειγμα,
// C++ program to overload sum() function #include using namespace std; // Function with 2 int parameters int sum(int num1, int num2) ( return num1 + num2; ) // Function with 2 double parameters double sum(double num1, double num2) ( return num1 + num2; ) // Function with 3 int parameters int sum(int num1, int num2, int num3) ( return num1 + num2 + num3; ) int main() ( // Call function with 2 int parameters cout << "Sum 1 = " << sum(5, 6) << endl; // Call function with 2 double parameters cout << "Sum 2 = " << sum(5.5, 6.6) << endl; // Call function with 3 int parameters cout << "Sum 3 = " << sum(5, 6, 7) << endl; return 0; )
Παραγωγή
Άθροισμα 1 = 11 Άθροισμα 2 = 12,1 Άθροισμα 3 = 18
Εδώ, έχουμε δημιουργήσει 3 διαφορετικές sum()
λειτουργίες με διαφορετικές παραμέτρους (αριθμός / τύπος παραμέτρων). Και, με βάση τα ορίσματα που πέρασαν κατά τη διάρκεια μιας κλήσης συνάρτησης, καλείται ένα συγκεκριμένο sum()
.
Είναι ένας πολυμορφισμός χρόνου μεταγλώττισης επειδή ο μεταγλωττιστής ξέρει ποια λειτουργία πρέπει να εκτελεστεί πριν από την κατάρτιση του προγράμματος.
Για να μάθετε περισσότερα σχετικά με το, επισκεφτείτε το μάθημα υπερφόρτωσης λειτουργιών C ++.
Υπερφόρτωση χειριστή C ++
Στο C ++, μπορούμε να υπερφορτώσουμε έναν χειριστή όσο λειτουργούμε σε τύπους που καθορίζονται από τον χρήστη, όπως αντικείμενα ή δομές.
Δεν μπορούμε να χρησιμοποιήσουμε χειριστή υπερφόρτωση για βασικά είδη, όπως int
, double
κ.λπ.
Η υπερφόρτωση χειριστή είναι βασικά η υπερφόρτωση λειτουργίας, όπου διαφορετικές λειτουργίες χειριστή έχουν το ίδιο σύμβολο αλλά διαφορετικούς τελεστές.
Και, ανάλογα με τους τελεστές, εκτελούνται διαφορετικές λειτουργίες χειριστή. Για παράδειγμα,
// C++ program to overload ++ when used as prefix #include using namespace std; class Count ( private: int value; public: // Constructor to initialize count to 5 Count() : value(5) () // Overload ++ when used as prefix void operator ++() ( value = value + 1; ) void display() ( cout << "Count: " << value << endl; ) ); int main() ( Count count1; // Call the "void operator ++()" function ++count1; count1.display(); return 0; )
Παραγωγή
Πλήθος: 6
Εδώ, έχουμε υπερφορτώσει τον ++
τελεστή, ο οποίος λειτουργεί σε αντικείμενα της Count
κλάσης (αντικείμενο 1 σε αυτήν την περίπτωση).
Χρησιμοποιήσαμε αυτόν τον υπερφορτωμένο χειριστή για να αυξήσουμε άμεσα τη μεταβλητή τιμής του αντικειμένου count1 κατά 1
.
Αυτό είναι επίσης ένας πολυμορφισμός μεταγλώττισης .
Για να μάθετε περισσότερα, επισκεφτείτε το σεμινάριο υπερφόρτωσης χειριστή C ++.
Παράκαμψη λειτουργίας C ++
Στην κληρονομιά C ++, μπορούμε να έχουμε την ίδια λειτουργία στη βασική τάξη, καθώς και στις παράγωγες τάξεις.
Όταν καλούμε τη συνάρτηση χρησιμοποιώντας ένα αντικείμενο της παραγόμενης κλάσης, η συνάρτηση της παραγόμενης κλάσης εκτελείται αντί εκείνης στην βασική κλάση.
Έτσι, εκτελούνται διαφορετικές συναρτήσεις ανάλογα με το αντικείμενο που καλεί τη συνάρτηση.
Αυτό είναι γνωστό ως παράκαμψη συνάρτησης στο C ++. Για παράδειγμα,
// C++ program to demonstrate function overriding #include using namespace std; class Base ( public: virtual void print() ( cout << "Base Function" << endl; ) ); class Derived : public Base ( public: void print() ( cout << "Derived Function" << endl; ) ); int main() ( Derived derived1; // Call print() function of Derived class derived1.print(); return 0; )
Παραγωγή
Παράγωγη συνάρτηση
Εδώ, χρησιμοποιήσαμε μια print()
συνάρτηση στην Base
τάξη και την ίδια συνάρτηση στην Derived
τάξη
Όταν καλούμε print()
χρησιμοποιώντας το Derived
αντικείμενο που προέρχεται1, παρακάμπτει τη print()
συνάρτηση Base
εκτελώντας τη print()
συνάρτηση της Derived
κλάσης.
Είναι ένας πολυμορφισμός χρόνου εκτέλεσης, επειδή η κλήση συνάρτησης δεν επιλύεται από τον μεταγλωττιστή, αλλά επιλύεται στον χρόνο εκτέλεσης.
Για να μάθετε περισσότερα, επισκεφθείτε τον οδηγό C ++ Function Overriding.
Εικονικές λειτουργίες C ++
Στο C ++, ενδέχεται να μην μπορούμε να παρακάμψουμε τις συναρτήσεις εάν χρησιμοποιήσουμε έναν δείκτη της βασικής κλάσης για να δείξουμε ένα αντικείμενο της παραγόμενης κλάσης.
Η χρήση εικονικών συναρτήσεων στην βασική κλάση διασφαλίζει ότι η συνάρτηση μπορεί να παρακαμφθεί σε αυτές τις περιπτώσεις.
Συνεπώς, οι εικονικές συναρτήσεις εμπίπτουν στην πραγματικότητα στην παράκαμψη της λειτουργίας . Για παράδειγμα,
// C++ program to demonstrate the use of virtual functions #include using namespace std; class Base ( public: virtual void print() ( cout << "Base Function" << endl; ) ); class Derived : public Base ( public: void print() ( cout << "Derived Function"
Output
Derived Function
Here, we have used a virtual function
print()
in the Base
class to ensure that it is overridden by the function in the Derived
class.
Virtual functions are runtime polymorphism.
To learn more, visit our C++ Virtual Functions tutorial.
Why Polymorphism?
Polymorphism allows us to create consistent code. For example,
Suppose we need to calculate the area of a circle and a square. To do so, we can create a
Shape
class and derive two classes Circle
and Square
from it.
In this case, it makes sense to create a function having the same name
calculateArea()
in both the derived classes rather than creating functions with different names, thus making our code more consistent.