Sobes.tech
Senior

Kako pozvati čistu virtuelnu metodu?

sobes.tech АИ

Одговор од АИ

Нije moguće direktno pozvati čistu virtuelnu metodu putem pokazivača na apstraktnu baznu klasu ili putem objekta te klase, jer ona nema definiciju u baznoj klasi.

Međutim, čista virtuelna metoda može biti pozvana iz konstruktora ili destruktora potomne klase, u kojoj ta metoda ima implementaciju. U tom slučaju, poziv će biti dozvoljen u statičkom režimu, i biće pozvana implementacija te klase u kojoj se poziv vrši.

Primer poziva iz konstruktora potomne klase:

#include <iostream>

class Base {
public:
    virtual void pure_virtual_method() = 0; // Čista virtuelna metoda
};

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

    Derived() {
        // Poziv čiste virtuelne metode iz konstruktora potomne klase
        pure_virtual_method();
    }
};

int main() {
    Derived obj; // Kreiranje objekta potomne klase, koji poziva konstruktor
    return 0;
}

U ovom primeru, prilikom kreiranja objekta obj klase Derived, biće pozvan konstruktor Derived, u kojem se dešava poziv pure_virtual_method(). Pošto u klasi Derived postoji implementacija te metode, ona će biti uspešno pozvana.

Pokušaj poziva čiste virtuelne metode iz konstruktora ili destruktora apstraktne bazne klase, u kojoj je ona deklarisana, izazvaće neodređeno ponašanje (undefined behavior), jer u trenutku izvršavanja konstruktora ili destruktora vtable bazne klase još nije potpuno izgrađena ili je već uništena, i odgovarajuća implementacija u potklasi nije dostupna.

Takođe, može se pozvati čista virtuelna metoda iz potklase koristeći kvalifikaciju oblasti vidljivosti (Base::pure_virtual_method()), ali to je moguće samo iz implementacije čiste virtuelne metode u potklasi, ako ona poziva implementaciju iz bazne klase (što za čistu virtuelnu metodu nije validno), ili drugu funkciju koja poziva čistu virtuelnu metodu (što takođe dovodi do neodređenog ponašanja), ili za poziv nevirtuelne metode sa istim imenom iz bazne klase.

Pravi način za rad sa logikom, predstavljenu čistom virtuelnom metodom, je kreiranje objekta potklase i pozivanje te logike putem pokazivača ili reference na baznu klasu (polimorfizam).

#include <iostream>

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

class Derived : public Base {
public:
    void pure_virtual_method() override {
        std::cout << "Implementacija u Derived putem polimorfizma\n";
    }
};

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

Dakle, "pozvati čistu virtuelnu metodu" u opštem smislu (kroz objekat ili pokazivač na bazni klasu koji nema definiciju) nije moguće. Poziv je moguć samo iz konstruktora ili destruktora potklase sa njenom implementacijom, ili indirektno, putem polimorfizma, kreiranjem objekta potklase.