سازنده ها در c++11، قسمت اول: محول کردن سازنده ها

اولا بگم که ترجمه کردن constructor delegating کار سختیه :ی
خوب! اصل قضیه اینه که معمولا بخش زیادی از کد سازنده های مختلف کلاسها شبیه هم هستند. این مشکل رو تو ‪C#‬ اینطور حل می کنم که یه متد مخفی مث init میسازم و بخشهای مشترک رو تو اونجا انجام می دم. اما c++03 این اجازه رو نمی داد. اما حالا c++11 این مشکل رو به زیبایی حل میکنه: سازنده های مختلف یک کلاس میتونن همدیگه رو صدا بزنن. به این ترتیب میشه یه سازنده اصلی داشت که سازنده های دیگه همشون اون رو صدا میزنن. اینجوری کد منظم تر و شکیل تر میشه.
اینم مثالش از ویکی پدیا:
[cpp]
class SomeType {
int number;

public:
SomeType(int new_number) : number(new_number) {}
SomeType() : SomeType(42) {}
};
[/cpp]

nullptr

تو ‪c++‬ برای پویینتری که به هیچ جایی اشاره نمی کرد از مقدار ۰ استفاده می شد. ماکرو NULL هم چیزی نبود به غیر از بازتعریف همین مقدار صفر. اما فرض کنید دو تا تابع به شکل زیر داریم:
[cpp]
void f(int);
void f(char *);
[/cpp]
حالا سوال اینه که تو فراخوانی به شکل زیر کدوم تابع باید صدا زده بشه؟
[cpp]
f(0);
[/cpp]
برای رفع این نقطه ابهام c++11 کلمه کلیدی nullptr رو پیشنهاد میکنه. nullptr با همه انواع پویینتر (از جمله پویینتر به تابع) سازگاره. مهمتر از اون اینکه یه راه استاندارد برای تفکیک مقدار دهی اشاره گر با انواع دیگه فراهم میکنه.

منبع

نصابهای آفلاین MinGW

MinGW یه کامپایلر برای c++ روی ویندوزه. این کامپایلر در واقع پوسته ای برای gcc گنوئه. نصاب خود MinGW یه فایل کوچیکه که فایلهایی رو که لازم داره از اینترنت دانلود میکنه. مشکل هم اینجاست که این روش نصب با اینترنت گازوییلی ما جور در نمیاد. اگرچه میشه این فایلهای دانلودی رو نگه داشت و با یه سری کلک برای دفعه های بعد هم ازشون استفاده کرد، اما روشهای بهتری هم هستن:

  • TDM-GCC که یه نصاب تر و تمیز فراهم میکنه. (من از فروم های codeblocks باهاش آشنا شدم.) تا روزی که این پست رو مینویسم هنوز ورژن ۴.۷ gcc رو پشتیبانی نمیکنه.
  • MinGW Distro که آخرین نگارش رو هم پشتیبانی میکنه. البته این یکی واقعا نصاب نیست. بلکه یه آرشیوه که اتوماتیک باز میشه. واسه همینم بعد باز شدنش بچ فایلی که تو دایرکتوری خروجیشه باید اجرا کرد.

کلیدهای میانبر در Eclipse و باقی قضایا

اینا یه سری کلیدهای میانبره که من در Eclipse/CDT زیاد استفاده می کنم:

  • Ctrl+M برای بزرگ کردن پنجره ادیتی که دارم روش کار میکنم
  • Ctrl+F11 اجرای برنامه
  • Ctrl+B بیلد کل فضای کار
  • Ctrl+Tab سوییچ بین هدر/سورس
  • Ctrl+Alt+Up/Down ایجاد یه کپی از خط جاری در بالا/پایین.

توجه کنید که میانبر آخری تو اوبونتو (و احتمالا سایر لینوکسها) کار نمیکنه. علت هم سادست: این میانبر به بالا پایین کردن ورک اسپیس تخصیص داده شده. برای به کار انداختن کافیه از تو System>Preferences>Keyboard Shortcuts گزینه های Switch to workspace above/below the current workspace رو پیدا کرد و کلیدهای میانبرشون رو از کار انداخت. (اگه رو گزینه ها Backspace زده بشه کلیدهای میانبر حذف میشن)

کلیدهای میانبر برای فولدینگ هم خیلی جالب نیستن. واسه همین عوضشون کردم (window>Preferences>General>Keys):

  • Ctrl+- فولد کردن بلوک Collapse
  • Ctrl++ باز کردن بلوک Expand
  • Ctrl+Shift+- فولد کردن همه بلوکها Collapse All
  • Ctrl+Shift++ باز کردن همه بلوکها Expand All

درضمن من از اینجا برای همیشه کد فولدینگ ادیتورم رو فعال کردم (به طور پیشفرض فعال نیست):

Window>Preferences>C/C++>Editor>Folding>Enable folding when opening a new window

 

پ.ن: فایل تنظیمات eclipse برای ادیتور و syntax highlighting رو اینجا آپلود کردم.

فراخوانی متدهای 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 به نمایش خواهد آمد. توضیحات بیشتر