Sobes.tech
Senior

Hoe roep je een pure virtuele methode aan?

sobes.tech AI

Antwoord van AI

Het is niet mogelijk om een pure virtuele methode rechtstreeks aan te roepen via een pointer naar de basisklasse met een abstracte methode of via een object van die klasse, omdat deze geen definitie heeft in de basisklasse.

Een pure virtuele methode kan echter worden aangeroepen vanuit de constructor of destructor van een afgeleide klasse, waarin deze methode een implementatie heeft. In dat geval wordt de oproep opgelost in statische modus, waarbij de implementatie van die klasse wordt aangeroepen waarin de oproep plaatsvindt.

Voorbeeld van een oproep vanuit de constructor van een afgeleide klasse:

#include <iostream>

class Base {
public:
    virtual void pure_virtual_method() = 0; // Pure virtuele methode
};

class Derived : public Base {
public:
    void pure_virtual_method() override {
        std::cout << "Implementatie in Derived\n";
    }

    Derived() {
        // Oproep van een pure virtuele methode vanuit de constructor van de afgeleide klasse
        pure_virtual_method();
    }
};

int main() {
    Derived obj; // Aanmaken van een object van de afgeleide klasse, die de constructor aanroept
    return 0;
}

In dit voorbeeld wordt bij het maken van het object obj van de klasse Derived, de constructor van Derived aangeroepen, waarin de oproep pure_virtual_method() plaatsvindt. Aangezien in Derived een implementatie van deze methode bestaat, wordt deze succesvol aangeroepen.

Proberen een pure virtuele methode aan te roepen vanuit de constructor of destructor van een abstracte basisklasse, waarin deze is gedeclareerd, zal leiden tot ongedefinieerd gedrag, omdat op het moment van uitvoeren van de constructor of destructor van de basisklasse de vtable nog niet volledig is opgebouwd of al is vernietigd, en de bijbehorende implementatie in de afgeleide klasse niet toegankelijk is.

Het is ook mogelijk om een pure virtuele methode aan te roepen vanuit een afgeleide klasse met behulp van de scope-kwalificatie (Base::pure_virtual_method()), maar dit is alleen mogelijk in de implementatie van de pure virtuele methode in de afgeleide klasse, als deze de implementatie van de basisklasse aanroept (wat niet mogelijk is voor een pure virtuele methode) of een andere functie die op haar beurt de pure virtuele methode aanroept (wat ook leidt tot ongedefinieerd gedrag), of om een niet-virtuele methode met dezelfde naam uit de basisklasse aan te roepen.

De juiste manier om te werken met de logica die wordt gepresenteerd door een pure virtuele methode, is door een object van de afgeleide klasse te maken en deze logica aan te roepen via een pointer of referentie naar de basisklasse (polymorfisme).

#include <iostream>

class Base {
public:
    virtual void pure_virtual_method() = 0;
};

class Derived : public Base {
public:
    void pure_virtual_method() override {
        std::cout << "Implementatie in Derived via polymorfisme\n";
    }
};

int main() {
    Base* ptr = new Derived(); // Polymorfe oproep
    ptr->pure_virtual_method();
    delete ptr;
    return 0;
}

Dus, "een pure virtuele methode aanroepen" in de algemene zin (via een object of pointer naar de basisklasse, zonder definitie) is niet mogelijk. De oproep kan alleen worden gedaan vanuit de constructor of destructor van de afgeleide klasse met de implementatie ervan, of indirect via polymorfisme, door een object van de afgeleide klasse te maken.