فراخوانی متدهای virtual در سازنده

خیلی خلاصه: هیچوقت از متدهای virtual در سازنده و نابودگر کلاس استفاده نکنید. در سی شارپ و جاوا استفاده از این نوع متدها مشکلی ایجاد نمیکند. اما در C++ متدهای virtual در سازنده و نابودگر کلاس نادیده گرفته شده و حتی در کلاسهای مشتق شده نیز متدهای کلاس پایه صدا زده می شوند.
مثال:
[cpp]
class base
{
public:
base()
{
init();
}
virtual void init()
{
cout<<"base"; } } class derived: public base { public: derived(): base() { } virtual void init() { cout<<"derived"; } } void f() { derived d; } [/cpp] در این مثال با فراخوانی سازنده کلاس derived در واقع انتظار داریم که روی صفحه عبارت derived نوشته شود، در صورتیکه در واقعیت عبارت base به نمایش خواهد آمد. توضیحات بیشتر

چرا destructor‌ یک کلاس با متدهای virtual باید virtual باشد؟

فرض کنید دو کلاس داریم که از هم ارث میبرند:
[cpp]
class classA
{
public:
virtual void func()
{
//simple code here
}
};

class classB: classA
{
public:
void func()
{
//resource consuming operations
}
~classB()
{
//releasing resources
}
};
[/cpp]
نکته مهم در اینجا اینه که classB برای صدازدن توابعش کلی از منابع سیستم مصرف میکنه. البته این کلاس نابود کننده خودش رو هم داره. اما به سناریوی زیر توجه کنید:
[cpp light=”true”]
classA* a = new classB();

//using a

delete a; // problem occurs here
[/cpp]
در اینجا اگرچه متغیر a از نوع classA است اما در واقع از classB استفاده میکنیم. اما موقع نابود کردن، چون متغیر از نوع classA بوده، نابودگر classB صدا زده نمیشه و منابع مصرف شده آزاد نمیشن. راه حل اینه که از همون اول نابود گر یه کلاس virtual رو به شکل virtual تعریف کرد. به این ترتیب نابودگرهای کلاسهای فرزند هم فراخوانی خواهند شد.