صفحه 1:
توابع مجازی
Virtual Function
صفحه 2:
re eee
مروری بر ارث بری
* فرایند ایجاد کلاسهای جدید از روی کلاسهای موجود را
ارث بری میگویند.
* تمام صفتها و رفتارهای کلاس پایه به کلاس مشتق منتقل
ميشود.
* کلاس مشتق میتواند علاوه بر صفات و رفتارهاى ارث برده
شده. دارای صفات و رفتارهای خاص خود نیز باشد.
صفحه 3:
! ۲۲۲۲۲"
class Base
{
public:
int a,b;
Base()
{
}
02
class Derrived:public Base
{
public:
int m,n;
Derrived()
{
a=5,b=7,m=13,n=15;
}
1:
صفحه 4:
مروری بر ارث بری-ادامه
* سازنده کلاس مشتق باید حداقل یکی ازسازنده های کلاس
پایه را فراخوانی نماید و چنانچه کلاس پایه سازنده پیش
فرض نداشته باشد این کار باید بصورت صریح در سازنده
* مخرب کلاس پایه بصورت خودکار در هنگام نابودی شی از
نوع کلاس مشتق بعداز اجرای مخرب کلاس مشتق. اجرا
میگردد.
صفحه 5:
a
مرور
ی بر ارث
بر
یادا
مه
@
تیوه فان میتوا
س يايه هد
نوع كلاس 5
ae cs gail :
“sabes 0
۱ متغيرها
ی از ز
j
نوع
صفحه 6:
ااا A
مروری بر ارث بری-دامه
* اشاره گرهای از نوع کلاس پایه میتوانند به اشیا از نوع كلاس مشتق
نیز اشاره کنند و نه بالعکس. عا له سس
Ornved d;
Orrived Pr;
bP r = &d; @
ات Pr = wow یه
Pir = ew Orrrived(); فيه
Pr = ew Oose(); %
صفحه 7:
ااا يي
مرورى بر ارث برى -ادامه
كلاس مشتق ميتواند توابعى همنام با توابع كلاس يايه داشته باشد كه حتى در تعداد و نوع
آركومانهاى يكسانند. در اينصورت اكر تابع براى شى مشتق فراخوانى شود اولويت با همان
تابع در كلاس مشتق ميباشد و اكر بخواهيم تابع موجود در كلاس يايه فراخوانى شود بايد
صراحتاً نام کلاس پایه را قبل از نام تابع بياوريم.
وال
ل] اكر اشاره كر از نوع كلاس يايه داشته باشيم كه به يك شى ازكلاس مشتق اشاره ميكند و يك تابع همنام
در هر دو كلاس بايه و مشتق وجود داشته باشد. در صورت فياخوانى تابع از طريق اشاره كر كداميى
اجرا خواهد شد؟
صفحه 8:
تعریف توابع مجازی:
مجازی یعنی در ظاهر وجود دارد اما در باطن وجود ندارد.
هنگام استفاده از توابع مجازی, برنامه ای که به نظر میرسد
تابعی از یک کلاس احضار میکند ممکن است عملاً تابعی
از کلاس دیگر را احضار کند
صفحه 9:
۲ SS ete
دلایل مطرح شدن توابع مجازی
* - آدرس متفیرهای از نوع كلاس مشتق میتوانند درون
اشاره گرهای از نوع کلاس پایه ذخیره شوند.
"ا ۲- زمانی که یک تابع عضو کلاس از طریق اشاره گر
فراخوانی ميشود. با توجه به نوع اشاره گر تابع مربوطه از
آن کلاس فراخوانی ميشود.
صفحه 10:
class Base void main()
{
public: Base varB;
void Show() Derived varD;
Base *ptr;
cout<<“Base Show” <<endl; ptr = &varB;
} ptr->Show();
1۶ ptr = &varD;
class Derived:public Base ptr->Show();
{ }
public:
void Show()
{
cout<<“Derived Show”<<end| الامطك5 ع5ج8
1 856 الامط5
ti
صفحه 11:
نتیجه تعریف تابع بصورت مجازی
* در صورتی که در مثال قبل تابع 5100۷۷ در کلاس پایه
(58856) بصورت مجازی (۷۱۳۲۷۵۱) تعریف شده
باشد شاهد اين خواهيم بود که در زمان اجرا تابع مربوط به
كلاس مربوطه فراخوانی ميشود.
صفحه 12:
void main()
Base varB;
Derived varD;
Base *ptr;
ptr = &varB;
ptr->Show();
ptr = &varD;
ptr->Show();
Base Show
لامط5 لع اتوعط
Base وت
pas void Show()
Show”<<endl; الا
1
class Derived:public Base
{
public:
void Show()
{
}
1
cout<<“Derived Show”<<end|
صفحه 13:
تقيد دير هنكام
* در مثال قبل هنگام کامپایل, کامپایلر نمیداند محتوای ۳0۴۲
به چه کلاسی اشاره میکند.
* محتواى آن ميتواند آدرس شيئى از كلاس 8856 باشد ویا
آدرس شيئى از كلاس Derived
"" هنكامى كه از توابع مجازى استفاده ميشود از آنجا كه
آدرس تابع هنكام اجرا معلوم ميشود به آن تقيد ديرهنكام
يا تقيد يويا ميكويند
* توابعی که از نوع مجازی نیستند هنگام کامپایل مشخص
میشود که چه تابعی باید فراخوانی شود که به آن تقید
زودهنگام یا تقید استاتیک میگویند
صفحه 14:
تقید دیرهنگام
* تقید دیرهنگام نیازمند مقداری سربار است اما به میزان
زیادی قویتر و انعطاف پذیرتر میباشد.
صفحه 15:
كلاس تجريدى و توابع مجازی محض
* کلاس 510206 را در مثال زیر درنظر بگیرید
* هیچ گاه ما یک شی از کلاس 51036 ایجاد نمیکنیم
ولی تنها از آن برای تعیین ویژ گیهای مشترک تمامی اشیا
استفاده میشود.
Shape
Circle Square Triangle
صفحه 16:
کلاس تجریدی و توابع مجازی محض
(ا دامه...)
* کلاس پایه ای را که هیچ شیئی از روی آن ایجاد نمیکنیم
کلاس تجریدی مینامند
* اگر یک تابع مجازی در کلاس را برابر با صفر قرار دهیم
به آن تابع مجازی محض میگویند.
* یک کلاس بعنوان کلاس تجریدی است اگر و تنها اگر
حداقل یک. تابع مجازی محض داشته باشد.
صفحه 17:
class CCircle:public Shape
{
private:
int
publ
void Draw(CDC *pdc)
{
pdc->Circle(x,y,r);
i
void main()
{
CShape *ptr;
CRectangle rc;
CCircle ci;
ptr = &rc;
Ptr->Draw();
ptr = &ci;
Ptr->Draw();
class CShape
{
private:
2 _ تابع مجاز: محض
pu ic: _———— Si é
irtual void Draw(CDC C *pde)=0;
ii ae
class CRectangle:public Shape
{
private:
int x1,y1,x2,y2;
public:
void Draw(CDC *pdc)
{
pdc->Rectangle(x1,y1,x2,y2);
7
1
صفحه 18:
۲۲۲۲۳ "
مخربها و توابع مجازی
* معمولاً مخربهای کلاسها را بصورت مجازی تعریف میکنیم
* به تکه برنامه زیر توجه کنید.
در صورتی که ما مخرب را در کلاس پایه بصورت مجازی
تعریف نکرده باشیم هنگامی که از دستور ۳۲ 061616
استفاده میکنیم مخرب کلاس پایه فراخوانی ميشود حال آنكه
میدانیم اين اشاره گر آدرس شیثی از نوع کلاس مشتق را حمل
میکرده است.
Base *Ptr;
Ptr = new Derived();
delete Ptr;
صفحه 19:
* کلاس پایه 510206 را تعریف کنید.
۴ تابع 0۲۵۷۷ را بصورت تابع مجازی محض تعریف نمایید
* تابع 66۳033۳۲۵۷۱56۲ را نیز بصورت مجازی عضو
کلاس 510206 تعریف کنید.
* از کلاس 5۱06 دو کلاس ۵6۲۵۴۵0۱6 و 1۲16 را
تعریف نمایید و دو تابع فوق را مجدد در این کلاسها تعریف نمایید به
گونه ای که اطلاعات مورد نیاز هر کلاس از کاربر گرفته شود و با
توجه به نوع كلاس ترسیم مناسبی داشته باشیم.
* درون برنامه یک اشاره گر از نوع 06 5]۱3* تعر یف نمایید.
* هنگام اجرا از کاربر بخواهید نوع شکل مورد نظرش را وارد کند و با
توجه به نوع درخواستی یک شی از آن نوع ساخته شود و پس از
گرفتن مشخصه های مود نیازش خودش را نمایش دهد.