Sobes.tech
Junior

Ինչ եք իմանում C++-ում virtual բանալի բառի մասին?

sobes.tech AI

Պատասխան AI-ից

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 { // `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 (վիրտուալ ֆունկցիաների աղյուսակ): Տաբլո վիրտուալ ֆունկցիաների ցուցակով դասի։ Ամեն օբյեկտ, որը ունի վիրտուալ ֆունկցիաներ, պարունակում է անտեսանելի ցուցակ (vptr) իր դասի vtable-ի վրա:
  • vptr (vtable ցուցակ): Անհրաժեշտ է ժամանակի ընթացքում կանչվող ֆունկցիայի որոշման համար:
  • = 0 (մաքուր վիրտուալ ֆունկցիա): Նշում է, որ ֆունկցիան չունի իրականացմանը այս դասում, դարձնելով այն աբստրակտ:
  • override (վերաշարադրանք): Մասնավորապես նշում է, որ ժառանգական դասի ֆունկցիան վերաշարադրում է բազային դասի վիրտուալ ֆունկցիան։ Օգնում է կոմպիլյատորին գտնել սխալները, եթե սիգնատուրան չի համընկնում:
  • final (վերջ): արգելում է վիրտուալ ֆունկցիայի կամ դասի հետագա վերաշարադրումը կամ ժառանգությունը:

Ամփոփում՝ virtual-ը հիմնական մեխանիզմն է պոլիմորֆիզմի իրականացման համար ժառանգության և դինամիկ կապի միջոցով C++-ում։