Sobes.tech
Junior

Šta znate o ključnoj reči virtual u C++?

sobes.tech АИ

Одговор од АИ

virtual у C++ се користи за проглашавање виртуелних функција у базној класи. Ово омогућава реализовање полиморфизма током извршавања (runtime polymorphism).

Примена:

  • Дефинише функцију у базној класи којом се може преклапати (override) у наследним класама.
  • При позиву виртуелне функције преко показивача или референце на базну класу, фактички се позива реализација функције у објекту наследне класе (ако је тамо преклапана). Ово се дешава током извршавања помоћу табеле виртуелних функција (vtable).

Главне тачке:

  • Виртуелне могу бити само чланске функције класе. Глобалне функције, статичке чланске функције и конструктори не могу бити виртуелни.
  • Деструктори могу и често треба да буду виртуелни, како би се избегли губици меморије приликом брисања објеката наследних класа преко показивача на базну класу.
  • Ако је функција проглашена virtual у базној класи, она аутоматски остаје виртуелна у свим наследним класама, чак и ако тамо није експлицитно коришћен virtual (иако се препоручује јасно назначавање virtual и override у наследним класама ради јасноће).
  • Чисто виртуелне функције се проглашавају са = 0 и чине класу апстрактном. Такву класу није могуће директно инстанцирати.

Пример:

#include <iostream>

class Base {
public:
    virtual void print() {
        std::cout << "From Base" << std::endl;
    }

    virtual ~Base() {
        std::cout << "Base destructor" << std::endl;
    }
};

class Derived : public Base {
public:
    void print() override { // Јасно назначавање преклапања
        std::cout << "From Derived" << std::endl;
    }

    ~Derived() override { // Јасно назначавање
        std::cout << "Derived destructor" << std::endl;
    }
};

int main() {
    Base* ptr = new Derived(); // Показивач на базну класу показује на објекат наследне

    ptr->print(); // Позива се Derived::print() због виртуелне функције
    delete ptr;   // Позивају се деструктори Derived, а затим и Base због виртуелног деструктора

    return 0;
}

Повезани појмови:

  • vtable (табела виртуелних функција): Табела показивача на виртуелне функције класе. Сваког објекта са виртуелним функцијама садржи невидљив показивач (vptr) на vtable своје класе.
  • vptr (показивач на vtable): Потребан за одређивање позване функције током извршавања.
  • = 0 (чиста виртуелна функција): Значи да функција нема реализацију у овом класе, чинећи је апстрактном.
  • override (презапис): Јасно указује да функција у наследној класи преклапа виртуелну функцију базне класе. Помаже компајлеру да пронађе грешке ако се сигнатура функције не поклапа.
  • final (крај): Забрањује даље преклапање виртуелне функције или наследство од класе.

Укратко: virtual је основни механизам за реализовање полиморфизма преко наслеђивања и динамичког везивања функција у C++.