Sobes.tech
Senior

Come chiamare un metodo virtuale puro?

sobes.tech AI

Risposta dell'AI

Non è possibile chiamare direttamente un metodo virtuale puro tramite un puntatore alla classe base con un metodo astratto o tramite un oggetto di questa classe, poiché non ha una definizione nella classe base.

Tuttavia, un metodo virtuale puro può essere chiamato dal costruttore o dal distruttore di una classe derivata, in cui questo metodo ha un'implementazione. In tal caso, la chiamata sarà risolta in modalità statica, chiamando l'implementazione di quella classe in cui avviene la chiamata.

Esempio di chiamata dal costruttore di una classe derivata:

#include <iostream>

class Base {
public:
    virtual void pure_virtual_method() = 0; // Metodo virtuale puro
};

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

    Derived() {
        // Chiamata di metodo virtuale puro dal costruttore della classe derivata
        pure_virtual_method();
    }
};

int main() {
    Derived obj; // Creazione di un oggetto della classe derivata, che chiama il costruttore
    return 0;
}

In questo esempio, creando l'oggetto obj della classe Derived, viene chiamato il costruttore di Derived, nel quale si effettua la chiamata a pure_virtual_method(). Poiché in Derived esiste un'implementazione di questo metodo, viene chiamato con successo.

Tentare di chiamare un metodo virtuale puro dal costruttore o dal distruttore di una classe base astratta, in cui è dichiarato, comporta un comportamento indefinito, poiché al momento dell'esecuzione del costruttore o del distruttore della classe base, la vtable non è ancora completamente costruita o è già stata distrutta, e l'implementazione corrispondente nella classe derivata non è accessibile.

È anche possibile chiamare un metodo virtuale puro da una classe derivata usando la qualificazione dello scope (Base::pure_virtual_method()), ma ciò è possibile solo nell'implementazione del metodo virtuale puro nella classe derivata, se questa chiama l'implementazione della classe base (cosa che non è possibile per un metodo virtuale puro) o un'altra funzione che a sua volta chiama il metodo virtuale puro (anch'esso comporta un comportamento indefinito), o per chiamare un metodo non virtuale con lo stesso nome nella classe base.

Il modo corretto di interagire con la logica rappresentata da un metodo virtuale puro è creare un oggetto della classe derivata e chiamare questa logica tramite un puntatore o riferimento alla classe base (polimorfismo).

#include <iostream>

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

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

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

Pertanto, "chiamare un metodo virtuale puro" nel senso comune (tramite un oggetto o un puntatore alla classe base, senza definizione) non è possibile. La chiamata può avvenire solo dal costruttore o dal distruttore della classe derivata con la sua implementazione, o indirettamente, tramite il polimorfismo, creando un oggetto della classe derivata.