Sobes.tech
Senior

Comment appeler une méthode virtuelle pure?

sobes.tech IA

Réponse de l'IA

Il n'est pas possible d'appeler directement une méthode virtuelle pure via un pointeur vers la classe de base avec une méthode abstraite ou via un objet de cette classe, car elle n'a pas de définition dans la classe de base.

Cependant, une méthode virtuelle pure peut être appelée depuis le constructeur ou le destructeur d'une classe dérivée, dans laquelle cette méthode a une implémentation. Dans ce cas, l'appel sera résolu en mode statique, en appelant l'implémentation de cette classe dans laquelle l'appel est effectué.

Exemple d'appel depuis le constructeur d'une classe dérivée :

#include <iostream>

class Base {
public:
    virtual void pure_virtual_method() = 0; // Méthode virtuelle pure
};

class Derived : public Base {
public:
    void pure_virtual_method() override {
        std::cout << "Implémentation dans Derived\n";
    }

    Derived() {
        // Appel d'une méthode virtuelle pure depuis le constructeur de la classe dérivée
        pure_virtual_method();
    }
};

int main() {
    Derived obj; // Création d'un objet de la classe dérivée, appelant le constructeur
    return 0;
}

Dans cet exemple, lors de la création de l'objet obj de la classe Derived, le constructeur de Derived est appelé, dans lequel se trouve l'appel à pure_virtual_method(). Étant donné que cette méthode a une implémentation dans Derived, elle sera appelée avec succès.

Tenter d'appeler une méthode virtuelle pure depuis le constructeur ou le destructeur d'une classe de base abstraite, dans laquelle elle est déclarée, entraînera un comportement indéfini, car au moment de l'exécution du constructeur ou du destructeur de la classe de base, la vtable n'est pas encore complètement construite ou a déjà été détruite, et l'implémentation correspondante dans la classe dérivée n'est pas accessible.

Il est également possible d'appeler une méthode virtuelle pure depuis une classe dérivée en utilisant la qualification du scope (Base::pure_virtual_method()), mais cela n'est possible que dans l'implémentation de la méthode virtuelle pure dans la classe dérivée, si elle appelle l'implémentation de la classe de base (ce qui n'est pas possible pour une méthode virtuelle pure) ou une autre fonction qui à son tour appelle la méthode virtuelle pure (ce qui conduit également à un comportement indéfini), ou pour appeler une méthode non virtuelle avec le même nom dans la classe de base.

La façon correcte d'interagir avec la logique présentée par une méthode virtuelle pure consiste à créer un objet de la classe dérivée et à appeler cette logique via un pointeur ou une référence à la classe de base (polymorphisme).

#include <iostream>

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

class Derived : public Base {
public:
    void pure_virtual_method() override {
        std::cout << "Implémentation dans Derived via polymorphisme\n";
    }
};

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

Ainsi, "appeler une méthode virtuelle pure" dans le sens courant (via un objet ou un pointeur vers la classe de base sans définition) n'est pas possible. L'appel ne peut être effectué que depuis le constructeur ou le destructeur de la classe dérivée avec sa propre implémentation, ou indirectement, via le polymorphisme, en créant un objet de la classe dérivée.