در شیگرایی میتونیم یه کلاس تعریف کنیم و چند تا فرزند براش تعریف کنیم مثلاً به صورت زیر
class Shape
{
};
class Rectangle : public Shape
{
};
class Circle : public Shape
{
};
حالا فرض کنیم تابعی داریم که در هر دو تا فرزند وجود داره ولی در هر فرزند به یه صورت مجزا عمل میکنه مثلاً تابع رسم
class Shape
{
};
class Rectangle : public Shape
{
void draw() const
{
}
};
class Circle : public Shape
{
void draw() const
{
}
};
خب در این صورت میشه برای هر دو تا شی تعریف شده رسم رو فراخوان کرد
Rectangle R();
R.draw();
Circle C();
C.draw();
یه چیزی داریم توی شیگرایی به نام نوع پویا یا نوع داینامیک. یعنی یه اشارهگر به والد میتونه به فرزند اشاره کنه
Shape *S1 = new Circle();
Shape *S2 = new Rectangle();
حالا در صورتی که بخوایم تابع رسم رو برای دو اشارهگر بالا فراخوانی کنیم اشکالی وجود داره. تابع برای کلاس Shape تعریف نشده. بنابراین باید برای Shape هم تابع draw() رو تعریف کنیم.
class Shape
{
void draw() const
{
}
};
اما در صورتی که برای S1 و S1 تابع رسم رو فراخوانی کنیم تابعی که اجرا میشه، تابع draw مربوط به Shape هست نه Rectangle یا Circle.
مشکل رو با تابع مجازی یا virtual رفع میکنیم. تابع مجازی در کلاس والد معرفی میشه بدون پیادهسازی و همون تابع در فرزندها تعریف میشه با پیادهسازی. بنابراین وقتی تابع مجازی اجرا بشه، تابع مربوط به فرزند مربوط اجرا میشه
S1->draw();
تابع draw مربوط به کلاس Circle رو اجرا میکنه
S2->draw();
تابع draw مربوط به کلاس Rectangle رو اجرا میکنه
هیچ پژوهش انسانی نمیتواند ادعای علمی بودن داشته باشد، مگر اینکه از برهان ریاضی برخوردار باشد (لئوناردو داوینچی)