Sobes.tech
Senior

Cum se apelează o metodă virtuală pură?

sobes.tech AI

Răspuns de la AI

Nu este posibil să apelați metoda virtuală pură direct printr-un pointer la clasa de bază cu o metodă abstractă sau printr-un obiect al acestei clase, deoarece nu are o definiție în clasa de bază.

Cu toate acestea, o metodă virtuală pură poate fi apelată din constructorul sau destructorul unei clase derivate, în care această metodă are o implementare. În acest caz, apelul va fi rezolvat în modul static, apelând implementarea acelei clase în care are loc apelul.

Exemplu de apel din constructorul unei clase derivate:

#include <iostream>

class Base {
public:
    virtual void pure_virtual_method() = 0; // Metodă virtuală pură
};

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

    Derived() {
        // Apelul metodei virtuale pure din constructorul clasei derivate
        pure_virtual_method();
    }
};

int main() {
    Derived obj; // Crearea unui obiect al clasei derivate, care apelează constructorul
    return 0;
}

În acest exemplu, la crearea obiectului obj al clasei Derived, va fi apelat constructorul Derived, în care se face apelul pure_virtual_method(). Deoarece în Derived există o implementare a acestei metode, ea va fi apelată cu succes.

Încercarea de a apela o metodă virtuală pură din constructorul sau destructorul unei clase de bază abstracte, în care este declarată, va duce la comportament nedefinit, deoarece în momentul execuției constructorului sau destructorului clasei de bază, vtable-ul nu este încă complet construit sau a fost deja distrus, iar implementarea corespunzătoare în clasa derivată nu este accesibilă.

De asemenea, se poate apela o metodă virtuală pură dintr-o clasă derivată folosind calificarea de domeniu (Base::pure_virtual_method()), dar acest lucru este posibil doar în implementarea metodei virtuale pure în clasa derivată, dacă ea apelează implementarea din clasa de bază (ceea ce nu este posibil pentru o metodă virtuală pură) sau o altă funcție care, la rândul său, apelează metoda virtuală pură (ceea ce duce, de asemenea, la comportament nedefinit), sau pentru a apela o metodă non-virtuală cu același nume din clasa de bază.

Modul corect de a interacționa cu logica prezentată de o metodă virtuală pură este de a crea un obiect al clasei derivate și de a apela această logică printr-un pointer sau referință la clasa de bază (polimorfism).

#include <iostream>

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

class Derived : public Base {
public:
    void pure_virtual_method() override {
        std::cout << "Implementare în Derived prin polimorfism\n";
    }
};

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

Prin urmare, "apelarea unei metode virtuale pure" în sensul comun (printr-un obiect sau pointer la clasa de bază, fără o definiție) nu este posibilă. Apelul poate fi făcut doar din constructorul sau destructorul clasei derivate cu implementarea sa, sau indirect, prin polimorfism, creând un obiect al clasei derivate.