Polymorfisme in C++ Begrijpen: Een Praktische Gids
Het woord polymorfisme betekent veel vormen hebben. Typisch treedt polymorfisme op wanneer er een hiërarchie van klassen is en ze gerelateerd zijn door inheritance (erfelijkheid).
C++ polymorfisme betekent dat een aanroep naar een member functie een andere functie zal laten uitvoeren, afhankelijk van het type object dat de functie aanroept.
Overweeg het volgende voorbeeld waar een base klasse afgeleid is door twee andere klassen:
Live Demo #include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a = 0, int b = 0){
width = a;
height = b;
}
int area() {
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape {
public:
Rectangle( int a = 0, int b = 0):Shape(a, b) {
}
int area () {
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape {
public:
Triangle( int a = 0, int b = 0):Shape(a, b) {
}
int area () {
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// Hoofdfunctie voor het programma
int main() {
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// sla het adres van Rectangle op
shape = &rec;
// roep rectangle area aan.
shape->area();
// sla het adres van Triangle op
shape = &tri;
// roep triangle area aan.
shape->area();
return 0;
}
Wanneer de bovenstaande code gecompileerd en uitgevoerd wordt, produceert het het volgende resultaat:
Parent class area : Parent class area :
De reden voor de incorrecte output is dat de aanroep van de functie area() eenmaal door de compiler ingesteld wordt als de versie gedefinieerd in de base klasse. Dit heet static resolution van de functieaanroep, of static linkage - de functieaanroep is vastgelegd voordat het programma uitgevoerd wordt. Dit wordt soms ook early binding genoemd omdat de area() functie tijdens de compilatie van het programma ingesteld wordt.
Maar nu, laten we een kleine wijziging in ons programma aanbrengen en de declaratie van area() in de Shape klasse voorafgaan met het trefwoord virtual zodat het er zo uitziet:
class Shape {
protected:
int width, height;
public:
Shape( int a = 0, int b = 0) {
width = a;
height = b;
}
virtual int area() {
cout << "Parent class area :" <<endl;
return 0;
}
};
Na deze kleine wijziging, wanneer de vorige voorbeeldcode gecompileerd en uitgevoerd wordt, produceert het het volgende resultaat:
Rectangle class area Triangle class area
Deze keer kijkt de compiler naar de inhoud van de pointer in plaats van het type. Daarom, aangezien adressen van objecten van tri en rec klassen opgeslagen zijn in *shape, wordt de respectieve area() functie aangeroepen.
Zoals u kunt zien, heeft elk van de child klassen een afzonderlijke implementatie voor de functie area(). Dit is hoe polymorfisme doorgaans gebruikt wordt. U heeft verschillende klassen met een functie van dezelfde naam, en zelfs dezelfde parameters, maar met verschillende implementaties.
Virtual Functie (Virtual Function)
Een virtual functie is een functie in een base klasse die gedeclareerd is met het trefwoord virtual. Het definiëren in een base klasse van een virtual functie, met een andere versie in een afgeleide klasse, signaleert aan de compiler dat we geen static linkage willen voor deze functie.
Wat we wel willen is dat de selectie van de functie die op elk gegeven moment in het programma aangeroepen wordt, gebaseerd is op het type object waarvoor het aangeroepen wordt. Dit soort operatie wordt aangeduid als dynamic linkage, of late binding.
Pure Virtual Functies (Pure Virtual Functions)
Het is mogelijk dat u een virtual functie in een base klasse wilt opnemen zodat het in een afgeleide klasse herdefinieerd kan worden om de objecten van die klasse te passen, maar dat er geen betekenisvolle definitie is die u voor de functie in de base klasse kunt geven.
We kunnen de virtual functie area() in de base klasse wijzigen in het volgende:
class Shape {
protected:
int width, height;
public:
Shape(int a = 0, int b = 0) {
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;
};
De = 0 vertelt de compiler dat de functie geen body heeft en de bovenstaande virtual functie zal pure virtual function genoemd worden.
C Taal
- C++ operators: complete gids met praktische voorbeelden
- Arrays doorgeven aan functies in C++: een praktische gids
- C++ klassen & objecten: praktische gids voor object-georiënteerd programmeren
- C++ Friend Functies en Friend Classes: Toegangscontrole Beheersen
- C++ Class Templates Beheersen: Een Praktische Gids
- C++ Operator Overloading – Praktische Handleiding met Code‑Voorbeelden
- Storage Classes in C++ Begrijpen: Scope, Levensduur en Gebruik
- C++ Overloading Beheersen: Functies & Operators Uitgelegd
- Data Abstractie in C++ Beheersen: Ontwerp Vereenvoudigen met Interface-Implementatie Scheiding
- Data Encapsulatie in C++: Uw Code Beschermen
- C++ Interfaces: Abstracte Klassen & Pure Virtual Functions Beheersen