Sobes.tech
Junior

რა იცით C++-ში virtual საკვანძო სიტყვაზე?

sobes.tech AI

პასუხი AI-სგან

virtual C++-да негизги класс ичинде виртуалдык функцияларды жарыялоо үчүн колдонулат. Бул убакытта (runtime polymorphism) полиморфизмди ишке ашырууга мүмкүндүк берет.

Колдонуу:

  • Негизги класс ичинде функцияны аныктайт, аны туундулары (override) кайра аныктоого болот.
  • Виртуалдык функцияны базалык класска көрсөтүүчү же шилтеме аркылуу чакырганда, чындыкта туундулардын объектинде функциянын ишке ашырылышы чакырылат (эгер ал ошол жерде кайра аныкталган болсо). Бул ишке ашуу виртуалдык функциялар таблицасы (vtable) аркылуу болот.

Негизги учурлар:

  • Виртуалдык функциялар гана класс мүчө функциялары болушу мүмкүн. Глобалдык функциялар, статикалык мүчө функциялар жана конструкторлор виртуалдык болбойт.
  • Деструкторлор да жана көбүнчө виртуалдык болушу керек, анткени базалык класска көрсөтүүчү аркылуу туундулардын объекттерин өчүрүүдө эс тутум чыгаштарын алдын алат.
  • Эгер функция virtual деп жарыяланган болсо, ал автоматтык түрдө бардык туундулардын класстарында виртуалдык бойдон калат, эгер ал жерде virtual колдонулбаса да (бирок аны ачык көрсөтүү сунушталат).
  • Чисто виртуалдык функциялар = 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 { // override колдонуу менен кайра аныктоо
        std::cout << "From Derived" << std::endl;
    }

    ~Derived() override { // override колдонуу
        std::cout << "Derived destructor" << std::endl;
    }
};

int main() {
    Base* ptr = new Derived(); // Базалык класс көрсөтүүчү туундулардын объектисине көрсөтүүчү

    ptr->print(); // Виртуалдык функциянын аркасында Derived::print() чакырылат
    delete ptr;   // Derived жана Base деструкторлору чакырылат, виртуалдык деструктор аркылуу

    return 0;
}

Тийиштүү түшүнүктөр:

  • vtable (виртуалдык функциялар таблицасы): Классдагы виртуалдык функцияларга көрсөтүүчү таблица. Ар бир виртуалдык функциясы бар объект өзүнүн классынын vtable-ына көз карандылык көрсөтүүчү (vptr) камтыйт.
  • vptr (vtable көрсөтүүчү): Ишке ашыруу учурунда чакырылуучу функцияны аныктоо үчүн керек.
  • = 0 (чисто виртуалдык функция): Бул функциянын ишке ашырылышы жок экенин билдирет, жана класс абстракттык болот.
  • override (өткөрүү): Жасалган функция базалык класстагы виртуалдык функцияны кайра аныктоону так көрсөтөт. Компиляторго каталарды табууга жардам берет, эгер функциянын сигнатурасы туура келбесе.
  • final (аяк): Виртуалдык функцияны же класс мураскорлугун болтурбайт.

Кыскасы, virtual — бул наследство жана динамикалык байланышты колдонуп полиморфизмди ишке ашыруунун негизги механизми.