تبدیل انواع (C++ / C Sharp)


برای تبدیل انواع مدیریت شده در محیط دات نت سه روش کلی موجود است که در زیر به آنها اشاره می کنیم.

روش اول : استفاده از تابع Convert :

تابع از پیش نوشته یشده ی Convert بسیاری از انوع موجود را به یکدیگر تبدیل می کند. نحو این تابع به صورت زیر است (عملگر دات ‘.’ در زبان سی شارپ معادل عملگر دبل کالن ‘::’ در زبان سی پلاس پلاس است) :

NewVariable = Convert.To”NewType” (OldVariable);

برای مثال برای تبدیل یک متغیر int به نوع String به صورت زیر عمل می کنیم.

int A;
String^ Str = Convert::ToString (A);


روش دوم : استفاده از تابع Parse یا TryParse :

تابع Parse یک رشته (String) را به انواع عددی تبدیل می کند. نحو کلی این تابع به صورت زیر است :

NewVariable = NewType::Parse (OldVariable);

برای مثال برای تبدیل String به نوع int به صورت زیر عمل می کنیم.

String^ str = “105”;
int A = Int32::Parse (str);

تابع Parse در صورت امکان عمل تبدیل را انجام می دهد ولش اگر ورودی صحیحی با آن داده نشود خطای زمان اجرا پیش می آید و برنامه از کار می افتد. بهتر است برای چک کردن ورودی و موفقیت آمیز بودن عمل تبدیل از تابع TryParse استفاده کنیم که خود در صورت وجود ورودی نامناسب ما را از آن آگاه سازد و خطای زمان اجرا پیش نیاید. تابع TryParse در صورت موفقیت آمیز بودن عمل تبدیل مقدار 1 و در غیر این صورت مقدار 0 را برمی گرداند.
حالت کلی تابع TryParse به صورت زیر است :

NewType::TryParse (OldVariable , NewVariable);

برای مثال برای تبدیل یک String به Double به صورت زیر عمل می کنیم:

String Str = “10.512”;
Double D = 0;
Double::TryParse (Str , D);


روش سوم : تبدیل آگاهانه انواع

کامپایلر شما را در شرایطی قرار نمیدهد که اطلاعات شما در معرض از دست رفتن قرار گیرند. هنگامی که در تبدیل انواع، اطلاعات در معرض خطر باشند کامپایلر بسته به شرایط و زبان برنامه نویسی یا از شما خطا می گیرد یا به شما در مورد آن اخطار می دهد. برای مثال تبدیل یک نوع int به نوع byte ممکن است باعث از دست رفتن اطلاعات شود؛ چون نوع byte ظرفیت کمتری از نوع int دارد. در این مواقع اگر خودتان آگاهانه میخواهید که این تبدیل را انجام دهید، میتوانید با استفاده از روش زیر این کار را انجام دهید تا کامپایلر بداند که خودتان نسبت به این موضوع آگاه هستید. حالت کلی این روش به صورت زیر است :

NewVariable = (NewType) OldVarable;

برای مثال برای تبدیل نوع int به نوع byte به صورت زیر عمل می کنیم.

int A = 245;
byte B = (byte) A;

آرایه ای از اشاره گر ها و اشاره گر ها به تابع (C++)


آرایه های می توانند دربر دارنده ی اشاره گر باشند، یعنی هر خانه ی آرایه یک اشاره گر باشد. در زیر مثال هایی از اعلان آرایه های از اشاره گر را مشاهده می کنید :

int* A [10];
string* B [10];

در بالا آرایه های A و B از نوع اشاره گر هایی به انواع int و string هستند. هر کدام از 10 خانه ی آرایه های بالا، یک اشاره گر مجزا هستند و می توانند یک جداگانه به یک متغیر اختصاص داده شوند. ارسال این آرایه ها به توابع، مشابه ارسال آرایه های معمولی است.

آرایه ای از "اشاره گر ها به توابع" :

در زیر نمونه ی ساده ی یک آرایه که هر خانه ی آن یک اشاره گر به یک تابع است، نشان داده شده است.

int (*ptr [10]) (int);

در بالا آرایه ای به نام ptr با 10 خانه، که هر کدام از انها اشاره گر به یک تابع با آرگومانی از نوع int هستند اعلان شده است. برای مثال می توانیم هر کدام از خانه های این آرایه را به تابع Square و Cube اختصاص دهیم.

int Square (int a)
{
    return a*a;
}
int Cube (int a)
{
    return a*a*a;
}

اختصاص اولین خانه ی آرایه ی ptr به تابع Square :

ptr [0] = Square;

اختصاص دومین خانه به تابع Cube :

ptr [1] = Cube;

استفاده از این اشاره گرها :

cout << ptr [0] (100);
cout << ptr [1] (100);

در بالا نمونه ی بسیار ساده از آرایه ای با عناصر اشاره گر مشاهده کردیم. میتوان هر کدام از خانه های این آرایه را به یک تابع اختصاص دهیم و در هنگام نیاز از انها استفاده کنیم. (البته به شرطی که این توابع متناسب با مشخصات تعریف شده برای آرایه باشند). برای مثال در بالا با فراخوانی خانه ی اول و دوم آرایه، مربع و مکعب ارگومان ارسالی محاسبه می شود. آرایه هایی از نوع اشاره گر یا اشاره به تابع را میتوان مانند آرایه های دیگر به توابع ارسال و از آنها استفاده کرد.

Linkin Park - Leave Out All the Rest


متن و ترجمه ی آهنگ بسیار زیبای Leave Out All the Rest از البوم سوم گروه Linkin Park به نام "دقایقی تا نیمه شب" (Minutes To Midnight) که در سال 2007 منتشر شده است.


I dreamed I was missing
خواب دیدم که گم شده بودم،
You were so scared
تو خیلی ترسیده بودی،
But no one would listen
ولی هیچکس گوش نمی کرد..
Cause no one else cared
به خاطر اینکه هیچکس اهمیتی نمیداد.
After my dreaming
بعد از این رویا،
I woke with this fear
با این ترس بیدار شدم که..
What am I leaving
چه چیزی از خود باقی می گذارم؟__
When I'm done here?
__ هنگامی که کارم اینجا تمام شود.
So if you're asking me
پس اگر از من می پرسی،
I want you to know
می خواهم که بدانی :
When my time comes
هنگامی که زمانش فرا رسد،
Forget the wrong that I've done
کارهای اشتباهی که انجام دادم را فراموش کن
Help me leave behind some
کمکم کن تا بتونم دلایلی را­­ __
Reasons to be missed
­­__ برای دلتنگ شدن برای من، باقی بگذارم. 

And don't resent me
و از من ناراحت نشو،
And when you're feeling empty
و هنگامی که احساس پوچی می کنی،
Keep me in your memory
مرا در حافظه ی خود نگهدار،
Leave out all the rest, leave out all the rest
مابقی را رها کن، مابقی را رها کن.

Don't be afraid
نترس،
I've taken my beating
من تاوان اینها را پس داده ام
I've shed but I'm me
من عوض شده ام،ولی هنوز "خودم" هستم.

I'm strong on the surface
من به ظاهر قوی هستم،
Not all the way through
نه در تمام شرایط.
I've never been perfect
من هیچگاه کامل نبودم...
But neither have you
ولی همچنین، نه حتی تو. (تو هم کامل نبودی)
So if you're asking me
پس اگر از من می پرسی،
I want you to know
می خواهم که بدانی :
When my time comes
Forget the wrong that I've done
Help me leave behind some
Reasons to be missed

Don't resent me
And when you're feeling empty
Keep me in your memory
Leave out all the rest, leave out all the rest

Forgetting all the hurt inside
فراموش کردن تمام رنج ها
You've learned to hide so well
که تو خیلی خوب یاد گرفته ای آنها را پنهان کنی
Pretending someone else can come
وانمود کردن اینکه کس دیگری میتواند بیاید __
And save me from myself
__ و من را از دست خودم نجات دهد،
I can't be who you are
من نمیتوانم آنچه تو هستی، باشم.

متن اصلی از سایت "MetroLyrics" .

Ludovic Bource


"لودویک بورس" (به انگلیسی: Ludovic Bource ) آهنگساز فرانسوی است که در حوزه ی موسیقی فیلم فعالیت می کند. نقطه ی اوج فعالیت وی، موسیقی متن فیلم بی کلام و سیاه و سفید "آرتیست" (The Artist) درسال 2011 بوده است که جوایز بفتا و گلدن گلوب در رشته ی "بهترین موسیقی متن" و چند جایزه ی دیگر را برای وی به ارمغان آورده است. 

لودویک بورس حرفه ی خود را با آهنگسازی برای کار های تبلیغاتی آغاز کرد و پس از آن به فیلم های کوتاه روی آورد. وی بیشترین همکاری را با کارگردان فرانسوی، آقای "میشل هازاناویسیوس" داشته است که اخرین آنها تا کنون فیلم آرتیست بوده است.  

چندریختی توابع (C++)  


"چندریختی" یا "چند شکلی" توابع یکی از مفاهیم و قابلیت های پایه در زبان های برنامه نویسی است. C++ نیز این قابلیت را پشتیبانی می کند و به شما امکان میدهد تا توابع همنام ولی با آرگومان های متفاوت ایجاد کنید. این قابلیت در توابع از پیش نوشته شده و توابعی که برنامه نویس ایجاد می کند، بسیار به کار رفته و میرود!
شما میتوانید توابعی توابعی همنام بنویسیود به شرطی که حد اقل یکی از شروط زیر را داشته باشند. (در غیر این صورت کامپایلر از شما خطا می گیرد):

- در تعداد آرگومان ها تفاوت داشته باشند.
- در نوع آرگومان ها تفاوت داشته باشند.

کامپایلر چگونه هنگام فراخوانی می تواند تشخیص دهد که باید از کدام تابع استفاده کند ؟ خب جواب این سوال در تعداد یا نوع آرگومان های ارسالی است. هنگام فراخوانی کامپایلر با توجه به آرگومان های ارسالی میتواند تشخیص دهد که کدام تابع مد نظر شما است. به نسخه های قابل استفاده هر تابع Overloading های تابع نیز گفته می شود. برای مثال تابع WriteLine که از توابع از پیش نوشته ی شده ی دات نت است، دارای بیش از 15 اورلودینگ است.
در زیر نمونه ی ساده از چندریخی یک تابع برای محاسبه ماکسیمم چند عدد را مشاهده می کنید.

int Max (int a, int b)
{
     return (a > b) ? a : b;
}

int Max (int a, int b, int c)
{
     return (a > b) && (a > c) ? a : (b > c) ? b : c;
}

float Max (float a, float b)
{
    return (a > b) ? a : b;
}

سه تابع بالا همنام هستند ولی پارامتر های آنها با یکدیگر یکسان نیست. در تابع اول، 2 پارامتر int ، در تابع دوم، 3 پارامتر int و در تابع سوم، 2 پارامتر float داریم. در هنگام استفاده از تابع Max با توجه به پارامتر هایی که به آن ارسال می کنیم، تابع مناسب انتخاب می شوند.

// first Function
Max (10, 13);

// second Function
Max (10, 12, 15);

// third Function
Max (10.2, 9.5);

اشاره گر به اشاء (C++)


اشاره گر ها میتوانند به اشیائ کلاس نیز اشاره داشته باشند. اشاره گر به یک شی به وسیله ی عملگر new ایجاد می شود.

class Sample
{ public :
int x , y;
void Print ()
{
     cout << "x= " << x << endl << "y= " << y << endl;
}

private :
}

اشاره گر به شیئی از کلاس Sample به صورت زیر تعریف و ساخته می شود.

Sample* Ptr = new Sample;

حالا اشاره گری به نام Ptr از نوع کلاس Sample در اختیار داریم. حالا چگونه به اعضا و توابع کلاس با این اشاره گر دسترسی پیدا کنیم؟ در C++ دو نحو مختلف برای این کار وجود دارد. برای مثال در زیر این دو روش برای دسترسی به عضو x از کلاس Sample آمده است :

(*Ptr).x = 100;
Ptr - > x = 100;

دو خط بالا تفاوتی با یکدیگر ندارند و هر دو یک کار را انجام میدهند؛ هر چند که بهتر است از روش دوم استفاده کنید. نکته ی مهم این است که در روش اول حتما باید اشاره گر (Ptr) و عملگر مقدار یابی (*) داخل پرانتز قرار گیرند به این دلیل که عملگر دات ( . ) دارای تقدم بالاتری نسبت به عملگر * است. البته در نظر داشته باشید که با ایجاد این اشاره گر، تابع سازنده کلاس نیز اجرا می شود و میتوان از آن طریق نیز شی را مقدار دهی کرد.
در C++ همچنین میتوان در داخل یک کلاس نیز اشاره گر هایی از نوع همان کلاس داشته باشیم. با این کار میتوان یک شی از کلاس را به شی دیگر ارتباط دهیم. 

توابع مرکب


تابه مرکب به تابعی گفته می شود که یک تابع دیگر را به عنوان آرگومان می پذیرد. این کار با استفاده از "اشاره گر به تابع" امکان پذیر می شود. در پست های قبلی اشاره گر به توابع را بررسی کردیم، حالا این اشاره گر را به یک تابع می فرستیم. واضح است که برای این کار تابع ما باید دارای آرگومان یا آرگومان هایی از جنس اشاره گر به تابع باشد. در زیر نمونه ی ساده ای از یک تابع مرکب را می بینیم.

int fact (int a)
{
int r = 1;
if (a == 0) return 0;

for (int i=a; i > 1; i--)
     r *= i;
return r;
}

int show (int (*ptr) (int) , int num)
{
for (int i=0; i < num; i++)
      cout << ptr (i) << endl;
}

در بالا دو تابع به نام های fact و show وجود دارند؛ تابع fact فاکتوریل عدد ارسالی را محاسبه می کند و تابع show برای نمایش اطلاعات به کار میرود. همینطور که می بینید تابع show دارای یک آرگومان از نوع اشاره گر به تابع است؛ یعنی میتواند یک تابع را به عنوان آرگومان بپذیرد. البته تابعی که متناسب با مشخصات اعلام شده در آرگومان باشد. یعنی یک آرگومان و نوع خروجی int داشته باشد. تابع fact این ویژگی ها را دارد پس میتوان اشاره گری به تابع fact را به تابع show ارسال کرد تا خروجی fact توسط show در خروجی چاپ شود. کد زیر این کار را انجام می دهد :

// main
int (*ptr) (int) = fact;
show (ptr , 10);

کد بالا اشاره گری به تابع به نام ptr تعریف کرده و آن را برابر تابع fact قرار می دهد. سپس این اشاره گر را در خط بعدی به تابع show ارسال می کند. نتیجه این کد چاپ فاکتوریل اعداد 0 تا 10 است. در این جا یکی از ساده ترین کاربرد های توابع مرکب و اشاره گر ها به توابع را دیدیم ولی در کارایی آنها بسیار گسترده تر از این ها است. البته در این جا هدف ما آشنایی هایی اولیه و مباحث مقدماتی است.

توابع بازگشتی (C++)


"تابع بازگشتی" ، تابعی است که در بدنه اش، همان تابع فراخوانی شده است. به عبارت بهتر، تابعی که خود را فراخوانی می کند. البته این فراخوانی می تواند غیر مستقیم نیز باشد؛ یعنی تابع اول ، تابع دیگری را فراخوانی می کند که در آن، تابع اول فراخوانی شده است.
استفاده از توابع به صورت بازگشتی در بسیاری از مواقع موجب کاهش کد نویسی می شود ولی باید در هنگام استفاده از انها دقت کرد. معمولا هنگامی که با حلقه های نا مشخص طرف هستیم یکی از راه ها استفاده از توابع بازگشتی است. برای مثال در پست های قبل برای نوشتن الگوریتم "مرتب سازی سریع" از توابع بازگشتی استفاده کردیم. حالت کلی توابع بازگشتی به صورت زیر است :

TYPE Function_Name (Arguments Declaration)
{
// Code / Condition

Function_Name (new Arguments);

// Code / Condition
}

توابع بازگشتی به صورت یک حلقه عمل می کنند و معمولا در هر بار آرگومان های متفاوتی به تابع ارسال می شود. واضح است که برای خروج از این حلقه باید یک شرط در تابع تعریف شود تا حلقه کنترل شود. در زیر مثالی از تابع بازگشتی آمده است که فاکتوریل یک عدد را محاسبه می کند.

int Fact (int a)
{
if (a > 1)
    return a*Fact(a-1);
else
    return 1;
}

در تابع بالا شرط a > 1 برای کنترل تابع استفاده شده است، اگر عدد 1 یا کوچکتر از آن به تابع ارسال شود، مقدار 1 بازگشت داده می شود و در غیر این صورت، تا زمانی که این شرط برقرار باشد، تابع Fact خود را فراخوانی می کند و در نهایت با رسیدن a به عدد 1، این حلقه یا "خود فراخوانی" خاتمه می یابد و تابع مقدار حاصل را باز می گرداند.

نابود کننده - Destructor


هنگامی که یک شی از کلاس ایجاد می شود تابع سازنده فراخوانی می شود تا مقدار دهی به آن را مدیریت کند؛ همین طور در هنگام آزاد شدن یک شی، تابع دیگری به نام "نابود کننده" یا "تخریب گر" فراخوانی می شود تا نابود شدن شی را مدیریت کند. تابع نابودکننده همنام کلاس و فاقد آرگومان و نوع خروجی است و قبل از نام آن علامت نقیض (~) استفاده می شود. مثالی از تابع سازنده و تابع نابود کننده برای یک کلاس :

calss Sample
{ public:
// Constructor
Sample ()
{
// code
}
// Destructor
~Sample ()
{
// code
}
}

اگر برای کلاسی تابع نابود کننده تعریف نشود، به طور خودکار یک نابودکننده ی پیشفرض برای آن تعریف می شود. مانند متغیر ها، اشیائ نیز در داخل بلوکشان معتبر هستند و پس از خارج شدن از هر بلوگ متغیر ها و اشیاء خودکار آن، نابود می شوند. برای مثال در زیر شیء Obj تنها در داخل بلوکی که در آن تعریف شده است، اعتبار دارد و پس از خارج شدن از این بلوک تابع نابودکننده فراخوانی می شود آن و Obj به پایان زندگی اش می رسد.

// main

{
// Object Created
Sample Obj;
}
// Object Destroyed

هنگامی که یک شی نابود می شود تمام متعلقات آن به غیر از اعضای ایستا (Static) آزاد می شوند. نکته ی دگر این است که هر کلاس تنها می تواند یک نابود کننده داشته باشد. گفتیم که اگر تابع نابودگر برای کلاس ایجاد نکنید، به صورت خودکار یک نابود کننده پیشفرض توسط کامپایلر برای آن ایجاد می شود. نابود کننده ی پیشفرض، اشیاءی که توسط عملگر new ایجاد شده اند را آزاد نمی کند. برای آزاد کردن این اشیاء باید به صورت دستی یک سازنده تعریف کنید که از عملگر delete برای آزاد کردن آنها استفاده کند.

اشاره گر به توابع (C++)


اشاره گر آدرس یک آدرس را در خود ذخیره می کند؛ تا اینجا اشاره گر هایی را دیدیم که آدرس یک متغیر ساده را در خود ذخیره می کردند. این اجازه می دهد تا از طریق یک اشاره گر، در زمان های مختلف به متغیر های مختلفی دسترسی داشته باشیم. اشاره گر ها همچنین می توانند آدرس یک تابع را در خود ذخیره کنند. این به شما اجازه می دهد تا از طریق اشاره گر، تابع را فراخوانی کنید.

واضح است که اشاره گر به تابع باید شامل آدرس حافظه تابعی که میخواهید آن را فراخوانی کنید، باشد. و برای اینکه اشاره گر درست کار کند باید اطلاعاتی در مورد آرگومان ها و نوع خروجی تابع داشته باشد. پس هنگامی که این اشاره گر را تعریف می کنید باید آرگومان ها و نوع خروجی تابع را مشخص کنید. و البته که هنگام استفاده از اشاره گر نیز باید آرگومان های صحیحی در آن استفاده کنید. حاالت کلی اعلان چنین اشاره گری به صورت زیر است :


Return_type (*Pointer_Name) (Arguments);


در این اعلان، ابتدا نوع خروجی، سپس نام اشاره گر (حتما) در بین دو پرانتز و پس از آن ارمان های تابعی که میخواهیم به آن اشاره کنیم آمده است. در زیر مثالی از یک اشاره گر به یک تابع آمده است.


int Cube (int a)
{
return a*a*a;
}
--------------------------
// in the main :
int (*ptr) (int) = Cube;
cout << ptr(10);
// Output : 1000

در بالا اشاره گر ptr به تابع Cube اشاره دارد. هر گاه از ptr استفاده کنیم تابه Cube فراخوانی می شود تا مکعب عدد ارسال شده را محاسبه کند.

سازنده ی کپی - Copy Constructor


در زبان C++ ، "سازنده ی کپی" تابعی است که برای ایجاد یک کپی از شی موجود به کار می رود. سازنده ی کپی مانند تابع سازنده، هنگام ایجاد یک شی جدید به صورت خودکار فراخوانی می شود و مشخصات یک شی موجود را به شی جدید نسبت می دهد. مانند تابع سازنده، سازنده ی کپی نیز همنام کلاس و فاقد نوع خروجی است با این تفاوت که در لیست آرگومان های سازنده ی کپی یک پارامتر به شیوه ی ارجاع ثابت از نوع کلاس، وجود دارد. این آرگومان در بردارنده ی شیئی است که قرار است کپی شود. حالت کلی تابع سازنده ی کپی به صورت زیر است :

Class_Name (const Class_Name& Name)
{
// Code
}

کد زیر مثالی از یک تابع سازنده ی کپی برای یک کلاس است.

class SHOW
{ public :
int x , y;
// Constructor
SHOW (int a, int y)
{
     x = a;
     y = b;
}
// Copy Constructor
SHOW (const SHOW& cpy)
{
     x = cpy.x;
     y = cpy.y;
}
}

در کلاس بالا یک تابع سازنده و یک سازنده ی کپی وجود دارد؛ ابتدا سازنده ی برای مقدار دهی اعضای کلاس استفاده شده است و سپس سازنده ی کپی مشخصات شی موجود (cpy) را در شی جدید قرار می دهد.
مانعی ندارد که یک تابع سازنده ی کپی چندین آرگومان نیز داشته باشد و همچنین مانند تابع سازنده میتوان برای مقدار دهی اعضای شی از "فهرست مقدار دهی" استفاده کرد. فهرست مقدار دهی نحو دیگری برای نوشتن بدنه ی تابه سازنده است و آن برای مثال بالا به صورت زیر است :

SHOW (const SHOW& cpy) : x (cpy.x) , y (cpy.y) { }

کد زیر توابع سازنده ی کلاس بالا را آزمایش می کند :

// main
SHOW obj1 (100, 200);
SHOW obj2 (obj1);

cout << obj2.x << endl;
cout << obj2.y << endl;

سازنده ها - Constructors


در زبان برنامه نویسی C++ ، "سازنده ها" توابعی هستند که (معمولا) برای مقدار دهی به متغیر ها یا اعضای یک شیء به کار می روند. این توابع به محض ایجاد یک شی از کلاس، فراخوانی و دستوراتشان اجرا می شوند. تابع سازنده همنام کلاس و فاقد نوع خروجی است. مثال زیر یک تابع سازنده برای کلاس را نشان می دهد :

class NAME
{ public:
// Constructor
NAME ()
{
     cout << "im a Constructor!";
}

};

کد بالا ساده ترین نمونه ی یک کلاس و تابع سازنده است که هیچ سودی برای ما ندارد و فقط هنگام ایجاد یک شی از کلاس NAME عبارت "im a Constructor!" بر روی صفحه چاپ می شود. تابع سازنده همیشه باید به صورت عمومی یا public تعریف شود. یک کلاس می تواند چندین تابع سازنده داشته باشد، به شرطی که لیست پارامتر های هر تابع با یکدیگر متفاوت باشد. به عبارت دیگر تابع سازنده میتواند مانند دیگر توابع به صورت "چند شکلی" نوشته شود. تابع سازنده ای که هیچ پارامتری ندارد به عنوان "سازنده ی پیشفرض" در نظر گرفته می شود. اگر کلاسی سازنده ی پیشفرض نداشته باشد یک سازنده ی پیشفرض به صورت خودکار برای آن ایجاد می شود. کد زیر مثالی از چند شکلی سازنده ها است :

class NAME
{ public :
NAME () { cout << "im a Constructor!";}
NAME (int a) { FIRST = a;}
NAME (int a , int b) {FIRST = a; SECOND = b;}
private :
int FIRST , SECOND;
}

در این مثال سه سازنده برای کلاس ایجاد شده است که به ترتیب دارای 0 ، 1 و 2 پارامتر هستند. با توجه به پارامتر ارسالی در هنگام ایجاد یک شی از کلاس، برنامه متوجه می شود که از کدام سازنده استفاده کند. سازنده های بالا تنها برای مقدار دهی دو عضو کلاس NAME به نام های FIRST و SECOND استفاده شده اند ولی سازنده های می توانند بسیار پیچیده و موثر تر از این ها باشند. میتوانیم از روش دیگری برای تعریف بدنه تابع سازنده استفاده کنیم که مخصوص سازنده ها ایجاد شده اند و به آن "فهرست مقدار دهی" گفته می شود.

NAME (int a , int b) : FIRST(a), SECOND(b) {}

خط بالا روش دیگری برای مقدار دهی اعضای یک کلاس با سازنده است و با این روش اول که در ابتدا استفاده شده است فرقی نمی کند. در این روش مقدار دهی ها پس از علامت کولن : به ترتیب آمده اند و پس از آن علامت {} آمده است که میتوانیم مابقی کد های لازم را در آن قرار دهیم.
همانگونه که گفتیم سازنده ها در هنگام ایجاد یک شی از کلاس فراخوانی می شوند.

// main
استفاده از اولین سازنده
NAME obj;
استفاده از دومین سازنده
NAME obj(100);
استفاده از سومین سازنده
NAME obj(100,200);

تعداد متغیر آرگومان های توابع (C++/CLI)

نحوه ی ایجاد یک تابع با تعداد متغیری از آرگومان ها در C++/CLI کمی با C++ استاندارد تفاوت دارد. C++/CLI به شما اجازه می دهد تا با تعریف یک آرایه به عنوان پارامتر تابع، که قبل از آن علامت سه نقطه (...) آمده است، بتوانید تعداد متغیری از آرگومان ها را به تابع ارسال کنید. حالت کلی این تابع به صورت زیر است :


TYPE Function_Name (... array < TYPE > ^ Name)
{
دستورات تابع

}


در این حالت، عناصر آرایه به ترتیب در بردارنده ی آرگومان های ارسالی می شوند. برای مثال تابع زیر تعداد دلخواهی از آرگومان های int را می پذیرد و میانگین آنها را محاسبه می کند.

double Average (... array < int > ^ numbers)
{
int sum = 0;
for (int i=0; i < numbers - > length; i++)
     sum += numbers[i];

return sum/numbers - > Length;
}

آزمایش تابع :

// main

cout << Average (10,12,15,18);
cout << endl;
cout << Average (10.25,12,31,25,17,54,22);

به این دلیل که در تعریف تابع از آرایه های CLR استفاده شده است، نیازی نیست که یک آرگومان جدا برای طول آرایه (تعداد آرگومان های ارسالی) تعریف شود؛ یکی از خواص این آرایه ها، "Length" است که طول آرایه را مشخص می کند. پس مشکلی برای مشخص کردن تعداد آرگومان ها و دستیابی به آنها وجود ندارد. همان گونه که میبینید استفاده از روش C++/CLI در مقایسه با روش Native C++ بسیار آسانتر است.    
 

متغیر های استاتیک در تابع (C++)


در یک تابع نمیتوان هر کاری را با متغیرهای خودکار (متغیر های معمولی) انجام داد. برای مثال نمی توان برای ذخیره تعداد فراخوانی یک تابع ، از یک متغیر خودکار استفاده کرد. به این خاطر که هر بار که تابع فراخوانی شود این متغیر ایجاد و با پایان تابع این متغیر نابود میشود. البته میتوان از روش هایی مانند استفاده از یک ارجاع (هر چند که این کار هم مشکلات خود را دارد)، یا یک متغیر عمومی، این کار را انجام داد؛ ولی در این جا هدف ما استفاده از متغیر استاتیک برای انجام این کار است.
برای ایجاد متغیری که با پایان تابع همچنان پابرجا باشد، می توان از متغیر را در تابع به صورت static اعلان کرد. تنها تفاوت اعلان آن با یک متغیر خودکار استفاده از کلمه کلیدی static قبل از نوع متغیر است.
تابع زیر نمونه ی ساده یک تابع است که تعداد دفعاتی که تابع اعلان شده است را بر می گرداند :

int Counter ()
{
static int Count;
return ++Count;
}

تکه کد زیر عملکرد این تابع را آزمایش می کند :

for (int i=0; i<10; i++)
Counter();

cout << Counter();

در کد بالا در حلقه ی for ده بار تابع Counter فراخوانی شده است و در خط آخر یک بار دیگر این تابع فراخوانی شده است؛ به این ترتیب عدد 11 در خروجی چاپ می شود. اما اگر متغیر Count را از نوع متغیر static تعریف نمی کردیم، مقدار 1 در خروجی چاپ می شد.

بازگشت اشاره گر و آدرس از تابع (C++)


در مورد ارسال ارجاع و اشاره گر به تابع در پست های قبلی صحبت کردیم، در این پست بازگشت انها به تابع اولیه را بررسی می کنیم.

فرض کنید Ptr یک اشاره گر باشد که به تابع ارسال شده است؛ با کد زیر مقدار متغیری که Ptr به آن اشاره دارد را به تابع اولیه بازگشت داده می شود.

return *Ptr;

نوع خروجی تابعی که کد بالا در آن استفاده شده است باید مناسب نوع Ptr باشد.
تابع زیر را در نظر بگیرید :

int* power (int input)
{
       int num = input*input;
       return & num;
}

این تابع بدون خطا کامپایل می شود و در حتی در برخی مواقع درست کار می کند؛ ولی کامپایار به شما هشدار می دهد : "بازگشت آدرس یک متغیر محلی یا موقتی" (returning address of local variable or temporary) . این پیام به شما هشدار می دهد که شما آدرس متغیری را استفاده می کنید که ممکن است همیشه وجود نداشته باشد. به این خاطر متغیر num در تابع power تنها تا زمانی که تابع در حال اجرا است وجود دارد و پس از عبارت return دیگر متغیری به نام num وجود ندارد و فضای اشغال شده توسط آن برای استفاده های دیگر خالی می شود. کد زیر که بخشی از تابع main است، مثالی از این موضوع است :

int* ptr = nullptr;
ptr = power (10);
string str = "hello world!";

cout << *ptr;

ما انتظار داریم که عدد 100 به عنوان خروجی در صفحه ی نمایش چاپ شود، ولی ممکن است با مقداری مواجه شویم که اصلا انتضار آن را نداشته باشیم. اگر خوش شانس باشیم و حافظه ی استفاده شده توسط num پس از نابود شدن آن توسط متغیری دیگری پر نشده باشد ما مقدار صحیحی را در خروجی می بینیم ولی از کجا می توان از این بابت مطمئن بود ؟! پس همیشه قانون کلی و مهم زیر را در نظر داشته باشید :
"هیچ گاه ادرس یک متغیر محلی را به تابع دیگری بر نگردانید"
حالا برای تصحیح تابع بالا چه می توان کرد ؟ خب راه های زیادی برای این کار وجود دارد ولی برای کاری که ما می خواهیم انجام دهیم یکی از انها استفاده از عملگر new برای ایجاد num اختصاص حافظه به آن است. کد زیر این کار را انجام می دهد :

int* power (int input)
{
       int* num = new int (input*input);
      return num;
}

با ایجاد متغیر num با استفاده از عملگر new ، این متغیر تا زمانی که با عملگر delete آزاد نشود یا برنامه به انتها نرسد، در حافظه باقی می ماند. حالا اگر در تابع main از تابع power استفاده کنیم به نتایج درستی دست پیدا می کنیم و دیگر کامپایلر اخطار بالا را نشان نمی دهد.

ivor horton's "Beginning Visual C++ 2010"

تعداد متغیر آرگومان های تابع (C++)


هنگامی که تابعی را اعلان می کنیم معمولا تعداد آرگومان هایی که به آن ارسال می شود را مشخص می کنیم. بعضی مواقع ممکن است تعداد آرگومان ارسالی همیشه یکسان نباشد؛ میتوان توابع را به صورتی تعریف کرد که تعداد متغیری از آرگومان ها را بپذیرند. مانند ادبیات با استفاده از علامت سه نقطه (...) می توان برای تابع مشخص کرد که تعداد ارگومان ها ادامه خواهند داشت. حالت کلی اعلان این تابع به صورت زیر است:

TYPE Function_name (Known Arguments , ...)
{
دستورات تابع
}

در این حالت حتما باید حداقل یک پارامتر مشخص وجود داشته باشد و علامت سه نقطه در آخر پارامتر ها بیاید. با این نوع اعلان هیچ اطلاعاتی در مورد نوع و تعداد پارامتر های مشخص نشده وجود ندارد؛ پس باید کدهای تابع خودشان تشخیص دهند که چه پارامتری به تابع ارسال شده است. کتابخانه ی بومی C++ در فایل < cstdarg > دستورات va_starts ، va_args و va_ends را تعریف کرده است که به شما در این کار کمک می کنند. این دستورات را با یک مثال بررسی می کنیم.

int sum (int Count , ...)
{
if (Count <= 0)
    return 0;

va_list arg_ptr;
va_start (arg_ptr, Count);

int Sum = 0;
for (int i=0; i  < Count; i++)   
      Sum += va_arg (arg_ptr, int);

va_end (arg_ptr);
return Sum;
}

در بالا تابعی به نام sum برای محاسبه مجموع چند عدد صحیح تعریف و نوشته شده است. این تابع یک آرگومان معلوم به نام Count دارد که تعداد ارگومان های ارسالی در آن مشخص می شود و مابقی ارگومان های تابع نامعلوم هستند.
در تابع اشاره گری به نام arg_ptr از نوع va_list که به لیست ارگومان ها اشاره دارد اعلان شده است. این نوع در فایل cstdarg تعریف شده است و وظیفه اش اشاره به هر یک از ارگومان ها، به ترتیب است.
در خط بعدی این اشاره گر در ماکرو va_start استفاده شده است. وظیفه va_start مقدار دهی کردن arg_ptr به اولین ارگومان تابع است. پارمتر دوم این ماکرو مشخص کردن اخرین پارامتر مشخص در تابع است. یعنی پارامتری که پس از ان پارامتر های نامعلوم شروع می شوند. در این مثال چون تنها یک پارامتر معلوم به نام Count داریم پس همان را به va_start می فرستیم.
پس از آن در حلقه for با استفاده از ماکرو va_arg به مقدار هر یک از آرگومان ها دست پیدا کرده و آن را در متغیر Sum ذخیره کرده ایم. ماکرو va_arg هر بار مقدار پارمتری که arg_ptr به آن اشاره می کند را بر می گرداند و اشاره گر arg_ptr را افزایش می دهد تا به ارگومان بعدی اشاره کند. پارامتر دوم va_arg نوع پارامتر ارسالی است که در این مثال عدد صحیح یا int می باشد. این پارامتر تعیین می کند که خروجی va_arg چه باشد و اشاره گر arg_ptr هر بار چقدر تغییر کند.
پس از پایان کار، با استفاده از va_end اشاره گر arg_ptr به null مقدار دهی می شود.
مثال زیر استفاده از تابع sum در تابع main یک بار با 6 ارگومان (مجموع 5 عدد صحیح) و یک بار با 8 ارگومان (مجموع 7 عدد صحیح) را نشان می دهد. ارگومان اول مشخص کننده ی تعداد ارگومان های بعدی است و حدف کردن آن باعث اشتباه محاسباتی می شود.

int a = sum (5 , 2,4,6,4,9);
int b = sum (7, 5,6,3,1,7,8,4);

Ivor horton's "Beginnig Visual C++ 2010"

آرگومان های تابع main


برای هر برنامه ی کنسولی در C++ یا C# باید یک تابع اصلی به نام main تعریف شود. اجرای برنامه از این تابع شروع می شود. در تعریف main میتوان آن را بدون پارامتر اعلان کرد (یا از کلمه void استفاده کرد) یا پارمتر هایی برای آن تعریف کرد که تابع بتواند اطلاعاتی را از Command Line دریافت کند. اطلاعاتی که در Command Line برای پارامتر های تابع main وارد می شود، همیشه به عنوان string تفسیر می شوند. برای مثال می توانید پارامتر های تابع main را به صورت زیر تعریف کنید (نام ها اختیاری هستند..):

void main (int argc, char* argv[])
{
دستورات 
}

پارامتر اول از نوع int ، تعداد رشته هایی است که در خط فرمان وارد می شود که شامل نام خود فایل اجرایی (نام برنامه) نیز می شود. پارامتر دوم، نگهدارنده ی اشاره گر هایی به آن رشته ها - به اضافه ی عنصر null - است. پس همیشه مقدار argc حداقل 1 و طول آرایه ی argv ، حداقل 2 است؛ چون حداقل باید نام برنامه را در خط فرمان وارد کنید تا برنامه اجرا شود. مقدار این دو پارامتر به ورودی شما در خط فرمان بستگی دارد. برای مثال اگر تنها نام برنامه را وارد کنید مانند:

Program_name.exe

تنها یک رشته که نام برنامه است به برنامه فرستاده می شود و در این صورت argc دارای مقدار 1 و argv دارای دو عنصر (یکی نام برنامه و دیگری null ) خواهد بود. همین طور اگر ورودی را به صورت زیر تغییر دهیم، مقدار و طول این دو پارامتر تغییر می کند.

Program_name.exe and some other information

گفتیم که تمام اطلاعاتی که به Command Line وارد می کنید به صورت string تفسیر می شود. فضای خالی (space) بین کلمات ورودی باعث تفکیک آنها می شود و باعث می شود که برنامه آنها را به عنوان یک رشته ی مجزا بشناسد. برای مثال ورودی زیر به عنوان 5 رشته تفسیر می شود و آنها تک تک در argv ذخیره می شوند.

Program_name.exe and 2 other names!
این رشته ها عبارتند از :
argv[0] = "Program_namr.exe"
argv[1] = "and"
argv[2] = "2"
argv[3] = "other"
argv[4] = "names"

اگر خواسته باشید یک رشته را به برنانه ارسال کنید که دارای فضای خالی (space) باشد و برنامه آن را به صورت یک رشته تک درنظر بگیرد، باید آن را بین دو علامت " قرار دهید. مانند زیر :

Program_name.exe "this is a test!"

در این صورت "this is a test" به عنوان یک رشته ی مستقل در نظر گرفته می شود. برای تست و آزمایش این اطلاعات بهتر است Command Prompt ویژوال استدیو یا Command Prompt ویندوز را باز کرده و خودتان روش های مختلف را امتحان کنید...
اگر از کار با Command Line راحت نیستید، می توانید در خود Visual Studio نیز این آرگومان ها را مشخص کنید. برای این کار به آدرس زیر بروید و اطلاعات خود را وارد کنید :

Project Properties > Configuration Properties > Debugging > Command Arguments


در ویژوال استدیو هنگامی که یک پروژه ی کنسولی را ایجاد می کنید، این آرگومان ها به صورت خودکار توسط IDE ایجاد می شوند. بعضی از پروژه ها از کد های مدیریت شده و برخی دیگر از کد های مدیریت نشده برای این کار استفاده می کنند. برای مثال در یک پروژه ی CLR ، این آرگومان ها به صورت زیر در می آید:

(array < System::String^ > ^ argv)

یا در C# به صورت زیر در می آید :

(string[] args)

در پروژه های مختلف نام و عملکرد این آرگومان ها کمی با هم متفاوت است ولی از دید کلی، همگی وظیفه یکسانی دارند.

Ivor Hortons "Beginnig Visual C++ 2010"

ارسال اشاره گر به تابع (C++)

هنگامی که از یک اشاره گر به عنوان یک پارامتر (یا آرگومان) به شیوه ی "مقدار" در توابع استفاده می کنید، یک کپی از اشاره گر ساخته می شود؛ این اشاره گر جدید دارای آدرس یکسانی با اشاره گر اولیه است، پس هر دو آنها به یک متغیر یا شیء اشاره دارند.

در زیر تابع Func ارگومانی از نوع اشاره گر دارد و از شیوه ی مقدار برای ارسال متغیر به آن استفاده شده است :

void Func (int* p)
{
       cout << *p

}

در تابع main نحوه ی فرستادن اشاره گر به تابع به صورت زیر است.


int a = 100;
int* Ptr = &a;
Func (Ptr);

این کد بدون هیچ مشکلی کار می کند ولی با این شیوه اگر اشاره گر تغییر داده شود در تابع main بدون تغییر باقی خواهد ماند چون از شیوه مقدار برای ارسال پارامتر ها به تابع استفاده شده است.
نکته : در تابع Func :

p++; // wont change "p" in the "main"
(*p)++; // change "a" in the "main" also

کد زیر تابع Func به روش "ارجاع" را نشان می دهد:

void Func (int*& p)
{
      cout << *p;
}

در تابع main نحوه ی استفاده از تابع Func به صورت زیر است.

int a = 100;
int* p = &a;
Func (p);

چون اشاره گر به صورت ارجاع به تابع فرستاده می شود، در صورت تغییر اشاره گر در تابع، در تابع main نیز اشاره گر تغییر می کند.
در تابع Func :

++p; // change "p" in the "main" also
(*p)++; // change "a" in the "main" also

اگر بخواهید متغیر ها به روش ارجاع به تابع ارسال شوند ولی تابع نتواند آنها تغییر دهد میتوانید از عملگر const در قبل از نوع پارمتر استفاده کنید. به این شیوه، ارسال متغیر به روش "ارجاع ثابت" گفته می شود. مزیت این روش این است که یک کپی از متغیر ایجاد نمی شود و حافظه بی جهت هدر نمی رود و همچنین محتوای متغیر توسط تابع قابل تغییر نخواهد بود.

Interior Pointers


گرچه نمیتوان بر روی هندل ها عملیات حسابی انجام داد، C++/CLI نوعی از اشاره گر را تدارک دیده است که میتوان بر روی آن عملیات حسابی انجام داد. این نوع، "اشاره گر های درونی" یا Interior Pointer نامیده می شود و به وسیله کلمه کلیدی interior_ptr تعریف می شود. آدرسی که در یک اشاره گر درونی ذخیره می شود میتواند در هنگام نیاز به وسیله ی زباله روب CLR آپدیت شود. ("زباله روب" یا Garbage Collector یک نوع سیستم مدیریت حافظه است که وظیفه اصلی آن خالی کردن خانه های بی استفاده ی حافظه است...). یک اشاره گر درونی همیشه یک متغیر خودکار است که برای یک تابع، متغیر محلی محسوب می شود. کد زیر یک اشاره گر درونی از نوع int تعریف می کند.

int a = 100;

interior_ptr < int > Ptr = &a;

کد بالا اشاره گری از نوع int اعلان کرده است و متغیر a را به آن نسبت داده است. (نوعی که اشاره گر به آن اشاره دارد بین دو علامت < > آمده است). اشاره گر Ptr این قابلیت را دارد که مانند اشاره گر های استاندارد C++ در عملیات های حسابی شرکت کند. کد زیر مثالی ساده از این موضوع است:

array < int > ^ a = {2,4,6,8,10};
interior_ptr < int > Ptr = &a[0];
cout << *Ptr;
// Prints: 2
Ptr++;
cout << *Ptr;
// Prints: 4

 اشاره های درونی در صورت مقدار دهی نشدن، به طور خودکار با nullptr مقدار دهی می شوند. تمام عملیات هایی که بر روی یک اشاره گر استاندارد قابل اجرا است، بر روی این نوع اشاره گر نیز قابل انجام است.

Ivor Horton's "Beginning Visual C++ 2010"

Tracking References - ارجاع های CLR

 
ارجاع های CLR مانند ارجاع های Native C++ ، یک نام مستعار برای یک متغیر ایجاد می کنند. ارجاع های CLR به صورت خودکار در صورت تغییر مکان متغیر اصلی توسط Garbage Collector ، به روز می شوند. میتوان برای متغیر هایی درون پشته (stack) و هندل های درون CLR heap ، ارجاع تعریف کرد. البته ارجاع های CLR همیشه در پشته ایجاد می شوند و نمیتوانند عضو یک کلاس باشند.

یک ارجاع CLR توسط عملگر % تعریف می شود. برای مثال کد زیر یک ارجاع به نام TR برای متغیر A ایجاد می کند.

int A = 100;
int% TR = A;
حالا می توان متغیر A را به وسلیه ی TR تغییر داد. یا در کل به جای A از TR استفاده کرد

TR = 200;
// now A = 200

همچنین عملگر % نیز مانند عملگر & برای ارسال متغیر ها به تابع به شیوه ارجاع به کار می رود. این عملگر مشابه عملگر "ref" در C# یا عملگر "ByRef" در Visual Basic است.  

انواع string در C++


string یا "رشته"، به معنی زنجیره ای از کاراکتر ها است. این نوع متغیر در برنامه نویسی بسیار پر کاربرد است. در زبان C++ چندین نوع مختلف برای رشته ها تعریف شده است و برای هر کدام خواص و توابع مخصوصی ایجاد شده است.


std::string :

نوع پایه و مدیریت نشده ی string در کتابخانه استاندارد C++ که به عنوان basic_string < char > تعریف شده است. برای کار با این نوع باید سر فایل < string > را به برنامه اضافه کنید. مثال :

using namespace std;
string str = "this is a std string";


std::wstring :
نوع گسترده ی string در کتابخانه ی استاندارد C++ که به صورت basic_string < wchar_t > تعریف شده است. مثال :

using namespace std;
wstring str = L"this is a wide_string";

System::String :
نوع مدیریت شده ی string که در محیط دات نت تعریف شده است. برای استفاده از این نوع باید پشتیبانی از CLR را در تنظیمات پروژه فعال کنید و از فضای نام System در برنامه استفاده کنید.

using namespace System;
String^ str = "this is a System string";


CString :
نوع پرکاربرد از string در برنامه نویسی MFC . اگر همراه با عملگر پیش پردازنده ی یونی کد ('L') تعریف شده باشد به عنوان رشته ای از کاراکتر های 16 بیتی که با کاراکتر 16 بیتی NUL خاتمه می یابند کامپایل شده و در غیر این صورت، به صورت رشته ای از کاراکتر های 8 بیتی که با کاراکتر 8 بیتی NUL خاتمه می یابند، کامپایل می شود. مثال :

CString str = "this is a CString";

CStringA :
نوعی 8 بیتی CString . این نوع همیشه به عنوان کاراکتر های 8 بیتی در نظر گرفته می شود حتی اگر یا عملکر پیش پردازنده ی یونی کد تعریف شده باشد.

CStringW :
نوع 16 بیتی CString . این نوع همیشه به عنوان کاراکتر های 16 بیت در نظر گرفته می شود حتی اگر عملگر پیش پردازنده ی یونی کد استفاده نشود.

CStringT :
نوعی مشابه نوع CString .

BSTR :
اشاره گری به رشته ای از کاراکتر های 16 بیتی که همچنین Basic String نیز نامیده می شود. با تابع SysAllocString() می توان آنها را مقدار دهی و با تابع SysFreeString() آنها را آزاد کرد. برای کار با این نوع باید سرفایل < comutil.h > را به برنامه اضافه کنید.
{علاوه بر اضافه کردن comutil.h در تنظیمات پروژه در مسیر زیر،  فایل comsuppw.lib را اضافه کنید:
Linker > Input > Additional Dependencies
{

bstr_t / _bstr_t :
یک شی _bstr_t ، خلاصه و متراکم کننده ی نوع داده ای BSTR است. برای استفاده از این نوع فایل < comutil.h > لازم است.

CComBSTR :
کلاس CComBSTR یک رپر (Wrapper) برای نوع BSTR است، که رشته های طول-پیشوندی هستند. طول رشته در یک متغیر int در مکانی در حافظه قبل از خود رشته، ذخیره می شود. این نوع نیازمند سرفایل < atlbase.h > است.

IntelliSense


IntelliSense (اینتلیسنس) نام فناوری "خودتکمیلی" (autocompletion) شرکت ماکروسافت برای استفاده در محیط های یکپارچه ی تولید نرم افزار (IDE) است. البته علاوه بر کامل کردن اتوماتیک کلمات در هنگام تایپ، اینتلیسنس در مستند سازی و ابهام زدایی نام متغیر ها، توابع، متد ها و کلاس ها کمک می کند و همچنین روشی مناسب جهت دستیابی به توضیحات توابع ، به ویژه لیست پارامتر های آنها است. اینتلیسنس سرعت برنامه نویسی را طور قابل ملاحظه ای افزایش می دهد؛ کاهش نیاز به تایپ کامل کدها و رجوع به مستندات و دیگر مراجع خارجی IDE، افزایش سرعت دسترسی به نام ها و پارامتر ها و عدم نیاز به حفظ بسیاری از نام ها از مزایای استفاده از این فناوری است.

اینتلیسنس برای اولین بار در Visual Basic 5.0 Control Creation Edition معرفی شد و پس از آن به سرعت به Visual FoxPro و Visual C++ و دیگر نرم افزار ها گسترش پیدا کرد. اینتلیسنس هم اکنون در محیط Visual Studio توسط ویرایشگر تمام زبان های برنامه نویسی آن پشتیبانی می شود. البته این قابلیت به دلایلی از زبان C++/CLI در Visual Studio 2010 حذف شده است ولی در نسخه ی Visual Studio 11 Developer Preview این قابلیت برای C++ بازگشته است. نرم افزار های جانبی مانند Visual Assist X به عنوان سیستم های خودتکمیلی خارجی برای Visual Studio نیز موجود هستند که می توانید از آنها استفاده کنید.

کلاس ConsoleKeyInfo


در .NET کلاس ConsoleKeyInfo برای خواندن و دریافت اطلاعات کلید زده شده از صفحه کلید به کار می رود. این کلاس در فضای نام System تعریف شده است. در زبان C++ کد زیر کلید زده شده از ضفحه کلید را می خواند.


ConsoleKeyInfo Name;

Name = Console::ReadKey (true);


در خط اول یک شی به نام Name از کلاس ConsoleKeyInfo ایجاد شده است؛ در خط دوم تابع ReadKey کلید زده شده توسط کاربر را می خواند و آن را در Name ذخیره می کند. (پارامتر "true" باعث می شود که کلید زده شده در صفحه نمایش چاپ نشود). خواص "Key" ، "KeyChar" و "Modifiers" برای نمایش اطلاعات کلید به کار می روند:

کلید زده شده : Key
کاراکتر یونی کد کلید زده شده : KeyChar
کلید های ترکیبی (Alt , Shift , Ctrl) : Modifiers

برای مثال کد زیر اطلاعات کلید فشرده شده را در خروجی چاپ می کند.

Console::WriteLine (Name.Key);
Console::WriteLine (Name.KeyChar);
Console::WriteLine (Name.Modifiers);

اگر کلید های alt ، ctrl و shift همراه با یک کلید فشرده شوند، Modifiers آنها را مشخص می کند و در غیر این صورت مقدار 0 را بر می گرداند.
(تابع getch() در سرفایل < conio.h > نیز کلید زده شده از صفحه کلید را می خواند)

کلاس StreamWriter و SreamReader


دو کلاس StreamWriter و StreamReader در محیط دات نت برای برای نوشتن و خواندن اطلاعات در/از فایل ها به کار ایجاد شده اند. برای استفاده از از این کلاس باید کدهای زیر را به برنامه اضافه کنید.

C# : using System.IO;
C++ : using namespace System.IO;

در زبان C++ کد زیر اطلاعات را در یک فایل دلخواه می نویسد. در خط اول ابتدا یک شی از کلاس StreamWriter ایجاد شده است و در خط دوم از تابع WriteLine برای نوشتن اطلاعات در فایل استفاده شده است.

StreamWriter Writer ("File Address");
Writer.WriteLine ("Text Information for Writing to File");
Writer.Close();


برای زبان C# :

StreamWriter Writer = new StreamWriter ("File Address");
Writer.WriteLine ("Information for Writing to File");
Writer.Close();


خواندن از فایل :

StreamReader Reader ("File Address");
// Read One Line
String^ Str = Reader.ReadLine();
// Read All
Str = Reader.ReadToEnd();

MessageBox در برنامه نویسی Windows Form

روش اول:

در یک برنامه Windows Form برای ایجاد MessageBox می توان از تابع Show() از کلاس MessageBox استفاده کرد. پارامتر های این تابع به 19 حالت مختلف قابل ارسال هستند که با استفاده از قابلیت intellisense میتوان تمام آنها را هنگام استفاده از تابع، مشاهده کرد. ساده ترین حالت آنها که فقط با یک پارامتر همراه است، به شکل زیر است :

MessageBox::Show ("Hello user !");


در این کد تنها متن پیام به تابه فرستاده شده است. برای کامل تر کردن این خط میتوان عنوان (Caption) و کلید های MessageBox را نیز تعیین کرد. (در صورت عدم تعیین کلید ها به صورت دستی، کلید OK به عنوان کلید پیشفرض MessageBox به کار می رود).

MessageBox::Show ("Hello User" , "Greeting" , MessageBoxButtons::OK);

Hello User : متن پیام
Greeting : عنوان MessageBox
MessageBoxButtons::OK : کلید پنجره ی MessageBox

روش دوم :

یکی دیگر از روش های ایجاد MessageBox استفاده از تابع MessageBox از کتابخانه ی Win32 است. روش استفاده از این تابع به صورت زیر است. برای استفاده از این تابه ابتدا فایل < comutil.h > را به برنامه الصاق کنید.

::MessageBox (a Handle to Window , Message, Caption, Buttons);

- پارامتر اول: از نوع HWND هندل به یک windows است. (این نوع در فایل WinDef.h تعریف شده است). (میتوان از "NULL" برای پارامتر اول استفاده کرد).
- پارامتر دوم: متن پیام است.
- پارامتر سوم: عنوان MessageBox .
- پارامتر چهارم: کلید های MessageBox .
مثال :

HWND* hw = new HWND();
::MessageBox (*hw, L"Hello world", L"Greeting", MB_OK);


MessageBox در برنامه نویسی MFC



MessageBox (یا "جعبه ی پیغام") یکی از ابزار های پرکاربرد در برنامه نویسی ویژوال به حساب می آید. بسیاری از مواقع لازم است توسط برنامه پیامی به کاربر داده شود یا از کاربر خواسته شود تا گزینه ای را انتخاب کند یا خطای اتفاق افتاده به کاربر گوش زد شود یا... در این مواقع استفاده از MessageBox بسیار مفید خواهد بود. MessageBox پنجره ای است که در صورت نیاز ظاهر می شود و پیامی را به کاربر می دهد. همه ی ما نمونه هایی از MessageBox را در هنگام بروز خطا (Error) در ویندوز یا سیستم عامل های دیگر یا برنامه های کاربردی مشاهده کرده ایم.
در برنامه نویسی MFC (برنامه نویسی به کمک کلاس های بنیادی ماکروسافت) تابع MessageBox() در کلاس CWnd  یا تابع عمومی MessageBox() در کتابخانه ی Win32 برای ایجاد MessageBox به کار می رود. (برای روش دوم باید از عملگر جداسازی دامنه "::" قبل از نام تابع استفاده کنید). حالت کلی استفاده از این تابع به صورت زیر است. 

MessageBox (Message , Caption, Buttons/Icons);


آرگومان های تابع MessageBox :

Message : متن پیام. (برای مثال از نوع CString یا LPCTSTR )
Caption : عنوان MessageBox . (از نوع CString یا LPCTSTR )
Buttons/Icons : دکمه ها (کلید ها) و ایکون های MessageBox .

مثال :

MessageBox ((LPCTSTR) L"Hello World!" , (LPCTSTR) L"Greeting", MB_OK);


دکمه های MessageBox :
به طور پیشفرض MessageBox دارای یک کلید "OK" خواهد بود. میتوان کلید های دیگری را به MessageBox اضافه کرد. در زیر برخی از ID کلید های استاندارد آمده است. (این ID ها درای ارزش عددی هستند):

OK : MB_OK
OK/Cancel : MB_OKCANCEL
Yes/No : MB_YESNO
Abort/Retry/Ignore : MB_ABORTRETRYIGNORE
Yes/No/Cancel : MB_YESNOCANCEL
Help : MB_HELP


آیکون های MessageBox :
MessageBox همچنین می تواند ایکون های گرافیکی مانند علامت سوال یا تعجب یا ... را همراه با متن نمایش دهد. ID برخی از این ایکون ها در زیر آمده است. این ID ها همراه با ID های کلید های MessageBox تعریف و با علامت | از هم جدا می شوند.

Warning : MB_ICONWARNING
Question : MB_ICONQUESTION
Stop : MB_ICONSTOP
Error : MB_ICONERROR

خروجی MessageBox :
هنگامی که MessageBox ظاهر می شود، کاربر باید با انتخاب یکی از دکمه ها برای مثال OK یا Cancel یا ...، آن را ببندد. تابع MessageBox خروجی از نوع int برمی گرداند. مقدار این خروجی نسبت به کلید زده شده متفاوت خواهد بود. با استفاده از این خروجی میتوان فهمید کاربر چه کلیدی را کلیک کرده است. هر کلید MessageBox دارای یک ID یا ارزش مشخص است، در زیر ID برخی از این کلید ها آمده است.

OK : IDOK
Cancel : IDCANCEL
Abort : IDABORT
Yes : IDYES
NO : IDNO
Retry : IDRETRY

مثال :


int a = MessageBox ((CString) "Do You Want to Continue?", (CString) "Warning", MB_OKCANCEL);

if (a == IDOK)
{
دستورات
}
 

MFC (مقدمات)


"کتابخانه ی کلاس بنیادی ماکروسافت" یا "کلاس های بنیادی ماکروسافت (Microsoft Foundation Classes) کتابخانه ای است که بخشی از رابط برنامه نویسی کاربردی (API) ویندوز را به صورت کلاس های C++ گرد آورده است. این کتابخانه مجموعه ای از توابع، ثابت ها، انواع و کلاس ها را برای برنامه نویسی برای ویندوز ارائه می کند.
MFC در سال 1992 در زمانی که کم کم C++ جای C در برنامه نویسی برای برنامه های کاربردی تجاری می گرفت، توسط ماکروسافت ارائه شد. در برنامه نویسی MFC ، استفاده مستقیم از API های ویندوز خیلی کم لازم می شود؛ در عوض برنامه اشیایی در کلاس های MFC ایجاد می کند و توابع عضو مربوط به آنها را صدا می زند. بسیاری از این توابع نام های یکسانی با API های مربوط به خود دارند.

مقدماتی از MFC :
در Visual Studio برای استفاده از قابلیت های کلاس های بنیادی ماکروسافت، باید پروژه ی خود را از نوع MFC Application ایجاد کنید.

File > New > Project > MFC Application


پس از انتخاب MFC Application و تایید آن پنجره ی به نام MFC Application wizard ظاهر می شود که در آن می توانید تنظیماتی در نوع پروژه ی خود ایجاد کنید. در انتها با انتخاب گزینه ی finish پروژه ی شما ساخته خواهد شد. بسیاری از کد نویسی های اولیه توسط IDE انجام می شود و پروژه برای اضافه کردن کد ها و رابط های گرافیکی کاربر آماده می شود. برای اضافه کردن رابط های گرافیکی مانند دکمه ها، پنل ها، چک باکس ها و... میتوان از دو روش کد نویسی یا استفاده از پنجره ی ToolBox استفاده کرد. که استفاده از ToolBoxو کشیدن و رها کردن (Drag & Drop) ابزار ها بر روی پنجره ی dialog برنامه، بسیار راحت تر از کد نویسی از ابتدا، است.
در برنامه نویسی MFC برای کار با کلیدها، تکست باکس ها، نوار ها و دیگر ابزار های رابط گرافیکی باید برای آنها متغیر تعریف کرد. این متغیر ها نماینده ی این ابزار ها هستند. برای اختصاص متغیر به این ابزار ها کافی است بر روی آنها کلیک راست کرده و گزینه ی Add Variable را انتخاب کنید و در پنجره ای که ظاهر می شود، نوع ، نام و .. مشخصات متغیر را تعیین کنید. این کار را با کد نویسی نیز می توانید انجام دهید ولی روش اول بسیار ساده تر است و کد نویسی به طور خودکار انجام می شود.


Ivor Horton

ترجمه ای از شرح زندگی نامه ی Ivor Horton نویسنده ی چندی از کتاب های آموزش برنامه نویسی ...

"ایور هورتون" به عنوان یک ریاضیدان فارق تحصیل شد و پس از آن با وعده ی "پاداش زیاد برای کار اندک" وارد عرصه ی فناوری اطلاعات شد. بر خلاف واقعیت، با وجود حجم کار بالا و در مقابل پاداش نه چندان زیاد، او تا به حال مشغول به کار با کامپیوتر ها است. او تا به حال در چند حوزه ی برنامه نویسی، طراحی سیستم، مشاوره، مدیریت و اجرای پروژه ها مختلف، درگیر بوده است. 
هورتون تجربه ی زیادی در طراحی و پیاده سازی سیستم های کامپیوتری به کار رفته در طراحی مهندسی و عملیات تولید در صنایع مختلف دارد. همچنین در زمینه ی توسعه ی نرم افزار های مخصوص و مفید در گستره ی وسیعی از زبان های برنامه نویسی و آموزش برنامه نویسی دارای تجربه ی بالایی است. او بیش از پانزده سال است که کتاب های آموزش زبان های برنامه نویسی مانند C ، C++ و Java را تالیف می کند.

Handle


handle (هندل) نوعی اشاره گر هوشمند (یا اشاره گر نوعی هندل!) به حساب می آید. هندل دارای تشابهاتی با اشاره گر های معمولی C++ است ولی تفاوت های مهمی نیز با آنها دارد. هندل یک آدرس را در خود ذخیره می کند که به طور مداوم به وسیله Garbage Collector (زباله روب) در صورت تغییر مکان شی ارجاع شده، آپدیت می شود. البته نمیتوان بر روی هندل مانند اشاره گر های معمولی، عملیات حسابی انجام داد.
هندل ها برای ارجاع به اشیایی که بر روی CLR heap ایجاد می شوند، استفاده می شوند. تمام اشیایی که از نوع کلاس ارجاع هستند، بر روی heap ذخیره می شوند؛ بنابر این متغیر هایی که شما برای ارجاع به آن اشیاء ایجاد می کنید باید یک هندل باشند. برای مثال کلاس String یک نوع کلاس ارجاع است، پس متغیر های که اشیاء String اشاره ارجاع دارند، باید یک هندل باشند. حافظه برای انواع کلاس مقداری به طور پیشفرض بر روی stack یا "پشته" (محلی برای ذخیره و بازیابی داده ها) اختصاص می یابد. ولی می توان با استفاده از عملگر gcnew متغیر ها را بر روی heap ذخیره کرد. متغیر هایی که در CLR heap ذخیره شده اند (که شامل تمام انواع ارجاع CLR نیز می شوند) نمی توانند به صورت عمومی اعلان شوند.

برای ایجاد یک هندل برای یک نوع مشخص باید پس از آوردن نوع، از علامت ^ استفاده کرد. برای مثال برای اعلان یک هندل به نام "Name" که بتواند آدرس یک شی String را ذخیره کند به صورت زیر عمل می کنیم :

String^ Name;


این کد یک هندل به نام Name از نوع String^ ایجاد می کند. هنگامی که یک هندل را اعلان می کنید، به صورت خودکار با null مقدار دهی می شود؛ (یعنی به هیچ چیز اشاره نمی کند.) برای اینکه به صورت دستی یک هندل را برابر null قرار دهید، باید از کلمه کلیدی nullptr استفاده کنید. مانند زیر :

Name = nullptr;

اگر یک هندل را با مقدار 0 مقدار دهی کنید، مقدار 0 به نوعی که هندل به آن اشاره دارد، تبدیل می شود و مقدار این شی جدید در هندل ذخیره می شود.
(کلمه ی کلیدی nullptr در C++/CLI با Native C++ تفاوت دارد؛ البته اگر در برنامه خود کد های Native را با کد های CLI به صورت مخلوط استفاده نمی کنید، این تفاوت اهمیتی ندارد. ولی اگر از هر دو نوع کد استفاده می کنید باید از کلمه ی _nullptr برای کد های Native و از nullptr برای کد های CLI استفاده کنید.)
هندل ها را می توان مانند متغیر ها در هنگام اعلان، مقدار دهی کرد. در مثال بالا ، کد زیر هنگام اعلان هندل آن را مقدار دهی می کند:

String^ Name (L"this is a System_string");

این خط یک شی String بر روی heap ایجاد می کند و مقدار داخل پرانتز را به آن نسبت می دهد. نوع رشته ی کاراکتری بالا در حقیقت یک const wchar_t* است، تعریف شدن string ها به این صورت این امکان را می دهد که به این شکل مقدار دهی شوند.
خط زیر یک هندل برای نوع int اعلان و مقدار دهی می کند:

int^ Name (100);

Name یک هندل به نوع int است که دارای مقدار 100 است. این هندل نمیتواند در عملیات حسابی شرکت کند، مگر حالتی که مقدار یابی (یا ارجاع یابی) شود. برای این کار مانند اشاره گر های معمولی از عملگر * استفاده می شود. البته هنگامی که در کد ها، هندل در طرف چپ تساوی قرار گیرد نیازی به این کار نیست و کامپایلر این کار را انجام می دهد. (البته می توانید به صورت دستی نیز این کار را انجام دهید.).( هندل های string مانند اشاره گر های string کمی متفاوت از انواع دیگر هستند.)

// these Two Lines are the same
Name = 150;
*Name = 150;


Ivar Horton's "Beginning Visual C++ 2010"

Generic Programming (مقدمات)


"برنامه نویسی جنریک" ، یا "برنامه نویسی جامع" یا "برنامه نویسی کلی" یا .. سبکی در برنامه نویسی است که در آن نوع داده ی پارامتر ها (آرگومان ها) در آینده مشخص می شود. بسیاری از زبان های برنامه نویسی (با تفاوت هایی) این قابلیت را پشتیبانی می کنند. در زبان C++ الگو ها (قالب ها - templates ) توابع مخصوص کار بار انواع جنریک هستند. 
هنگامی که یک تابع یا یک کلاس برای پردازش اطلاعات می نویسید، بسیار دشوار و ناراحت کننده است که برای هر نوع داده ی ورودی، یک کلاس یا تابع مجزا بنویسید. (مخصوصا اگر کد ها برای تمام انواع، یکسان باشد.) در زبان C++ با استفاده از یک کلاس template می توان از تکرار بی هوده کد نویسی اجتناب کرد. برنامه نویسی جنریک با مفهوم "چند ریختی" در برنامه نویسی متفاوت است.
دو روش برای ایجاد یک ایجاد یک تابع یا کلاس template وجود دارد. استفاده از کلمه ی کلیدی class یا typename :


template < class identifier > function_declaration;
template < typename identifier > function_declaretion;


کلمه کلیدی typename یا class برای اعلان پارامتر های توابع (identifier) بین دو علامت < > به کار می رود. پس از اعلان پارامتر های ورودی و خروجی، می توانیم آنها را در بدنه ی تابع به کار ببریم. کد زیر مثالی از ایجاد یک کلاس الگو است که تابعی به نام Swap برای تعویض مقادیر دو پارامتر ارسالی دارد.


template < typename T >
class Swap_Class
{
public:
void Swap (T& a, T& b)
{
     T temp = a;
     a = b;
     b = temp;
}
};

از عملگر (&) برای فرستادن پارامتر ها به تابع به شیوه "ارجاع" استفاده شده است. برای استفاده از این کلاس در برنامه ابتدا باید یک شی از آن به صورت زیر تعریف شود.

Swap_Class < Type > Object_Name;

Object_Name نام شی ساخته شده از کلاس Swap_Class و Type نوع پارامتر ارسالی به تابع Swap است. فرستادن دو متغیر int به تابع Swap :

int a = 10;
int b = 20;
Class_Swap < int > Func;
Func.Swap (a, b);

مثال دیگر از تابع Swap بدون استفاده از کلاس :


template < typename T >
void Swap (T& a, T& b)
{
T temp = a;
a = b;
b = temp;
}

فرستادن دو متغیر int به تابع Swap :

int a =10;
int b =20;
Swap (a , b);

فرستادن دو متغیر string به تابع Swap :

string str1 = "string 1";
string str2 = "string 2";
Swap (str1, str2);

ادامه دارد.