سلام!

در جلسه های قبل یک اشاره گر از جنس کلاس پایه ساختیم و در آن آدرس یک کلاس وارث را ذخیره کردیم. سپس متوجّه شدیم که این اشاره گر تنها توانایی دسترسی به توابع و متغّیر های خود را دارد و هیچ دسترسی ای به عضوهای کلاس وارث ندارد (با این که آدرس کلاس وارث در آن ذخیره شده است). در این جلسه می خواهیم کاری کنیم که این اشاره گر بتواند به برخی از عضوهای کلاس وارث نیز دسترسی داشته باشد.

برای این کار باید تابعی مجازی بسازیم. برای ساخت یک تابع مجازی باید کلمه ی virtual را به ابتدای Prototype آن اضافه کنید. مثلا اگر بخواهید تابعی به نام f را به صورت مجازی بسازید باید به صورت زیر عمل کنید؛

virtual void f( Arguments... );

این تابع باید یک بدنه نیز داشته باشد. در کد زیر جا یک کلاس Base درست کرده ایم و در آن یک تابع مجازی ساخته ایم. فعلا از خاصیت های تابع مجازی استفاده ای نشده است.

#include <iostream>

class Base{
    public:
        virtual void speak();
};

void Base::speak(){
    std::cout << "Base!" << std::endl;
}

حالا در کلاسی به نام Derived (که وارث کلاس Base است) تابعی با همان Prototype تعریف می کنیم (درج کلمه ی virtual نیاز نیست). در کد زیر می توانید کلاس Derived را مشاهده کنید.

#include <iostream>

class Base{
    public:
        virtual void speak();
};

void Base::speak(){
    std::cout << "Base!" << std::endl;
}

class Derived : public Base{
    public:
        virtual void speak();
};

void Derived::speak(){
    std::cout << "Derived!" << std::endl;
}

حالا در تابع main از هر کدام از کلاس های Base و Derived یک Object بسازید و تابع speak را در آن ها صدا بزنید (مانند زیر کد). خروجی همانی خواهد بود که انتظارش را دارید. یعنی اگر تابع speak را با یک Object از کلاس Base صدا بزنید. خروجی Base و اگر این تابع را با یک Object از کلاس Derived صدا بزنید، خروجی Derived خواهد بود.

#include <iostream>

class Base{
    public:
        virtual void speak();
};

void Base::speak(){
    std::cout << "Base!" << std::endl;
}

class Derived : public Base{
    public:
        virtual void speak();
};

void Derived::speak(){
    std::cout << "Derived!" << std::endl;
}

int main(){
    Base base;
    base.speak();
    Derived derived;
    derived.speak();
    return 0;
}

حالا کاری را که جلسه ی پیش یاد گرفتید انجام دهید. یعنی یک اشاره گر از نوع Base بسازید و آدرس آن را برابر با آدرس یک Object از جنس Derived قرار دهید (کد زیر). حالا اگر تابع speak را با کمک اشاره گر صدا بزنید، خروجی برنامه Derived خواهد بود! یعنی ما توانسته ایم با کمک ایجاد یک تابع مجازی به تابعی در کلاس وارث دسترسی داشته باشیم!

#include <iostream>

class Base{
    public:
        virtual void speak();
};

void Base::speak(){
    std::cout << "Base!" << std::endl;
}

class Derived : public Base{
    public:
        virtual void speak();
};

void Derived::speak(){
    std::cout << "Derived!" << std::endl;
}

int main(){
    Derived derived;
    Base *base = &derived;
    base->speak();
    return 0;
}

جلسه ی بعد با تابع مجازی بیشتر آشنا خواهید شد.

موفق باشید!