Sobes.tech
Senior

Kuidas kutsuda välja puhas virtuaalne meetod?

sobes.tech AI

Vastus AI-lt

Otsene puhas virtuaalne meetod otse bassa klassi näidiseadja või selle klassi objekti kaudu on võimatu, kuna see ei ole määratletud baasiklassis.

Kuid, puhas virtuaalne meetod võib olla kutsutud välja konstruktorist või destruktorist pärandklassis, kus see meetod on realiseeritud. Sel juhul lubatakse väljakutse staatilises režiimis, kutsutakse välja selle klassi realiseerimine, kus väljakutse toimub.

Näide, kuidas kutsuda pärandklassi konstruktorist:

#include <iostream>

class Base {
public:
    virtual void pure_virtual_method() = 0; // Puhas virtuaalne meetod
};

class Derived : public Base {
public:
    void pure_virtual_method() override {
        std::cout << "Realiseerimine pärandklassis\n";
    }

    Derived() {
        // Puhas virtuaalse meetodi väljakutse pärandklassi konstruktorist
        pure_virtual_method();
    }
};

int main() {
    Derived obj; // Pärandklassi objekti loomine, mis kutsub välja konstruktor
    return 0;
}

Selles näites, kui luuakse obj objekti Derived klassist, kutsutakse välja Derived konstruktor, milles toimub pure_virtual_method() väljakutse. Kuna see meetod on realiseeritud Derived klassis, kutsutakse see edukalt välja.

Kui proovida kutsuda puhas virtuaalne meetod konstruktorist või destruktorist abstraktse baasiklassi, kus see on deklareeritud, toimub käitumise rikkumine (undefined behavior), kuna baasiklassi vtable ei ole veel täielikult üles ehitatud või on juba hävinud, ning vastavat realiseerimist pärandklassis ei ole saadaval.

Samuti saab kutsuda puhas virtuaalset meetodit pärandklassi kvalifikatsiooni (Base::pure_virtual_method()) kasutades, kuid see on võimalik ainult realiseerimise ajal, kui see meetod on realiseeritud pärandklassis, mis kutsub välja baasiklassi realiseerimise (mida puhas virtuaalne meetod ei tee), või muul viisil, mis omakorda kutsub välja puhta virtuaalse meetodi (mis samuti viib ebetäpsete käitumisteni), või kutsuda mitte-virtuaalset meetodit sama nimega baasiklassist.

Õige viis puhta virtuaalse meetodi kasutamiseks on luua pärandklassi objekt ja kutsuda seda funktsiooni läbi viitaja või viitaja baasiklassile (polümorfism):

#include <iostream>

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

class Derived : public Base {
public:
    void pure_virtual_method() override {
        std::cout << "Polümorfismi kaudu realiseerimine\n";
    }
};

int main() {
    Base* ptr = new Derived(); // Polümorfne väljakutse
    ptr->pure_virtual_method();
    delete ptr;
    return 0;
}

Seega, "puhta virtuaalse meetodi" kutsumine üldises mõttes (objekti või bassa klassi näidise kaudu, millel puudub määratlus) ei ole võimalik. Väljakutse on võimalik ainult pärandklassi konstruktorist või destruktorist selle realiseerimisega või kaudselt, kasutades polümorfismi, luues pärandklassi objekti.