چند ریختی یعنی این که چند تا نوع یا type متفاوت رابط یکسانی داشته باشند و بشه به شکل یکسانی بهشون دسترسی داشت.
داخل ++C این کار روی کلاس های مشتق شده از یک کلاس یکسان قابل انجامه یعنی این که میشه شی کلاس مشتق شده رو داخل اشاره گر از کلاس parent بزارید و توابع که بین کلاس مشتق شده و parent مشترک هست رو صدا بزنید .
مثلا :
#include <iostream>
struct Parent
{
virtual void foo(){std::cout<<"in parent\n";}
};
struct Child1:public Parent
{
void foo(){std::cout<<"in child1\n";}
};
struct Child2:public Parent
{
virtual void foo(){std::cout<<"in child2\n";}
};
int main()
{
//zakhire type haye motefavet dakhel parent*
Parent* ch1=new Child1;//ok
Parent* ch2=new Child2;//ok
Parent* pa=new Parent;//ok
ch1->foo();//in child1 chap mishe
ch2->foo();//in child2 chap mishe
pa->foo();//in parent chap mishe
delete ch1;
delete ch2;
delete pa;
}
چندریختی جاهایی استفاده میشه که نیاز داشته باشید بصورت generic کد بنویسید (یعنی این که یک کد خاص بنویسید که با انواع متقاوت کار کنه)
مثلا فرض کنید 3 تا کلاس دارید یک کلاس PushButton یک کلاس MainWindow که هر 2 تا از یک کلاس یکسان (اینجا MyObject ) ارث بردن .
class MyObject
{
public:
virtual void hide(){std::cout<<"Hiding MyObject\n";}
};
class PushButton:public MyObject
{
public:
void hide(){std::cout<<"Hiding button\n";}
};
class MainWindow:public MyObject
{
public:
void hide(){std::cout<<"Hiding MainWindow\n";}
};
حالا نیاز به یک تابع دارید که یک Object بگیره و اونو hide کنه .
آیا بجای این که برای MainWindow و PushButton هر کدوم یک تابع جدا بنویسید بهتر نیست که یک تابع بنویسید که یک کلاس نامعلوم بگیره و متد مخفی شدنش رو صدا بزنه؟
با استفاده از چند ریختی این کار شدنیه :
#include <iostream>
class MyObject
{
public:
virtual void hide(){std::cout<<"Hiding MyObject\n";}
};
class PushButton:public MyObject
{
public:
void hide(){std::cout<<"Hiding button\n";}
};
class MainWindow:public MyObject
{
public:
void hide(){std::cout<<"Hiding MainWindow\n";}
};
//voroodi function zir mitoone MyObecjt bashe
// ya har classi ke az MyObject ers borde masalan inja PushButton va MainWindow
void hideObject(MyObject* object)
{
object->hide();//inja tabe hide object seda zade mishe
}
int main()
{
PushButton* button=new PushButton;
MainWindow* window=new MainWindow;
hideObject(button);//hide button
hideObject(window);//hide window
}
http://coliru.stacked-crooked.com/a/acd97823311f5796
داخل کتابخانه Qt هم دقیقا همین کار انجام شده تمام کلاس های ui از QObject ارث بردن
وقتی که یک تابع می نویسید که قراره بر روی همه کلاس ها کار کنه شی از نوع QObject میگیرید مثل این سوال که تابع eventFilter چون ورودیش از نوع QObject هست. و بر روی هر نوعی حالا چه pushButton چه Widget و... هم کار می کنه.