چرا 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 تعریف کرد. به این ترتیب نابودگرهای کلاسهای فرزند هم فراخوانی خواهند شد.

کد نویسی C++‎ در vim

vim یکی از بهترین ویرایشگرهای موجود متنه. با استفاده از افزونه‌های مختلف به سادگی میشه از این ابزار به صورت یه IDE استفاده کرد. یکی از قابلیت‌های مهم یه IDE خوب، کامل کردن اتوماتیک کده که خیلی از IDE ها در مورد C++‎ باهاش مشکل دارن. علت این مشکل هم برمی‌گرده به نحو پیچیده این زبون برنامه‌نویسی. بین همه افزونه‌هایی که برای این کار وجود داره استفاده از ابزارهای مبتنی بر clang منطقی‌تر به نظر می‌رسه. clang یه کامپایلره که اطلاعات مراخل میانی کامپایل رو هم در اختیار برنامه‌ها قرار میده. با استفاده از این اطلاعات برنامه‌ها می‌تونن کارایی مثل تکمیل کد یا تعویض اسم متغیر رو به سادگی انجام بدن.
برای استفاده از clang در vim باید از افزونه clang_complete استفاده کرد. برای نصب این افزونه تو محیط ایکس از این راهنما کمک بگیرید. یه صفحه ویکی هم البته نوشتم برای مراحل اضافی که باید تو ویندوز انجام بشه.
دنیای آزاد، دنیای لذت بردن از امکاناته.

نمونه سازی با تاخیر در C++0x

template ها ابزار مهمی در برنامه نویسی C++‎ هستند. در این روش برنامه سازی، قالب یک کلاس یا تابع بر اساس یک پارامتر مجهول نوشته می‌شود. ترجمه این قطعه از کد تا زمانی که آن پارامتر صراحتا به کامپایلر اعلام شود به تاخیر می‌افتد. اعلام پارامتر مجهول به کامپایلر سبب می‌شود که نمونه‌ای از آن قالب با نوع مشخص ایجاد شود که به این عمل نمونه‌سازی یا instantiating گفته می‌شود. تا قبل از زمان نمونه سازی به علت وجود پارامتر مجهول، کامپایلر توانایی ترجمه کد را ندارد.
[cpp light=”true”]template class std::vector;[/cpp]
طبق استاندارد C++‎، کامپایلر موظف بود دقیقا در هرجایی که پارامترهای یک template به طور کامل اعلام شد نمونه‌ای از آن بسازد. این روش نمونه‌سازی دو مشکل داشت:

  • ممکن بود نمونه‌سازی در جاهای مختلفی از کد انجام شود. در این صورت کامپایلر مجبور به دوباره کاری می‌شد و نهایتا نتیجه کند شدن فرایند کامپایل بود.
  • به علت اینکه در لحظه نمونه‌سازی کامپایلر نیاز داشت که تمام کد قالب در دسترس باشد، جدا کردن فایل هدر از سورس ممکن نبود.

برای حل این مشکلات extern template class توسط C++0x معرفی شد:
[cpp light=”true”]extern template class std::vector;[/cpp]
با این روش، نمونه‌سازی با تاخیر انجام شده و از مشکلات بالا جلوگیری می‌شود.