ایجاد و راه اندازی Event

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

public delegate void HANDLER();


// Class with an event member
public ref class EventClass
{
public:
// declaring the event
event HANDLER^ EVENT;

// Function to trigger event
void TriggerEvent()
{
   EVENT();
}
};

   

کلاس EventClass دارای یک Event وهله ای (instance) به نام EVENT است که با استفاده از دلیگیت HANDLER تعریف شده است و با آن در ارتباط است. و تابع عمومی TriggerEnevt مسئول راه اندازی این Event و در این مثال، بدون پارامتر است. هنگامی که EVENT راه اندازی می شود، میتواند توابعی که در لیست دلیگیت هستند را فراخوانی کند و همچنین نوع خروجی تعریف شده آن را داشته باشد. همینطور که می بینید راه اندازی Event مشابه فراخوانی دلیگیت است. برای جواب دادن به این Event میتوان کلاسی مشابه زیر ایجاد کرد :


public ref class AnswerClass

{
public:
void answer()
{
   Console::WriteLine("Event triggered");
}
};

کلاس AnswerClass دارای یک تابع عمومی به نام answer است که می تواند برای جواب دادن به Event به کار رود به این خاطر که دارای پارمتر ها و نوع بازگشتی یکسان با دلیگیت تعریف شده ما است.(در این مثال برای سهولت، هر دو بدون پارامتر و نوع بازگشتی هستند). 

به کار گیری Event :
قبل از اینکه بتوانیم از این تابع استافده کنیم باید یک شی از کلاس EventClass ایجاد کنیم. خط اول کد زیر این کار را انجام می دهد. بعد از اینکار میتوانیم این تابع را برای مدیریت Event خود ثبت کنیم.


EventClass^ obj = gcnew EventClass;

AnswerClass^ answer = gcnew AnswerClass;
obj -> EVENT += gcnew HANDLER(answer, & AnswerClass::answer);
obj ->TriggerEvent();

خط دوم کد بالا یک شی از کلاس AnswerClass ایجاد می کند، چون تابع answer یک تابع وهله ای (غیر استاتیک) است و سپس در خط بعد نمونه ای (وهله ای) از دلیگیت HANDLER را به همراه تابع مدیریت کننده خود را به Event تعریف شده در کلاس EventClass اضافه می کنیم؛ به عبارت دیگر تابع answer را برای Event خود ثبت می کنیم. در خط بعد با استفاده از تابع TriggerEvent آن را راه اندازی می کنیم. با فراخوانی این تابع، EVENT راه اندازی می شود و نتیجه ی آن، فراخوانی تابع answer است و در نتیجه عبارت "Event triggerd" در خروجی چاپ می شود.

منبع : Ivor Horton's beginnig visual C++ 2010

دلیگیت های آزاد - Unbound Delegates


در پست های قبل دلیگیت هایی که تعریف کردیم از نوع "دلیگیت های محدود" یا Bound Delegates بودند، زیرا آنها مجموعه ی ثابتی از توابع را در لیست فراخوانی خود داشتند. یک دلیگیت "نامحدود" یا "آزاد" به تابعی وهله ای (Instance) اشاره می کند که دارای لیست پارامتر مشخص شده و نوع بازگشتی برای یک نوع شی مشخص شده است. بنابراین یک دلیگیت یکسان میتواند برای فراخوانی توابع وهله ای برای هر شی مشخص شده به کار رود. در زیر نمونه ای از تعریف یک دلیگیت آزاد را مشاهده می کنید.

public delegate void HANDLER (HandlerClass^ , int value);

اولین آرگومان نوع اشاره گر this را مشخص می کند، برای اینکه یک دلیگیت از نوع HANDLER بتواند یک تابع وهله ای (غیر استاتیک) را فراخوانی کند. این تابع باید یک آرگومان از نوع int و نوع بازگشتی void داشته باشد. بنابراین یک دلیگیت از نوع HANDLER تنها میتواند یک تابع برای یک شی از کلاس HandlerClass را فراخوانی کند ولی برای هر شی از این نوع. این ممکن است کمی محدود کننده به نظر برسد ولی در بسیار مفید خواهد بود. فرض کنید HandlerClass ساختاری مشابه زیر دارد ...

ref class HandlerClass
{public:
// constructors ...
....
// functions
void Function1 (...)
{// do something}
void Function2 (...)
{// do something}
...
}

میتوان یک دلیگیت از نوع HANDLER را به صورت زیر ایجاد کرد:

HANDLER^ handler = gcnew HANDLER (&HandlerClass::Function1);

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

HandlerClass^ obj = gcnew HandlerClass ("parameters");
handler (obj, "value");

اولین آرگومان یک هندل به شی کلاس HandlerCalss است که شما با ارسال پارامتر ها به سازنده کلاس، ایجاد کردید که تعداد آنها بسته به تعریف سازنده است. دومین ارگومان مقداری است که به تابع موردنظر ارسال می کنید.
دلیگیت های آزاد را نیز میتوان با استفاده از عملگر های + و - در یکدیگر ادغام یا از یکدیگر تفکیک کرد. برای مثال بالا فرض کنید که بخواهید تابع دیگری از کلاس را به لیست دلیگیت اضافه کنید. با استفاده از عملگر + این کار به صورت زیر امکان پذیر است.

handler += gcnew HANDLER (&HandlerClass::Function2);

رزولوشن (تفکیک پذیری) 4K و 8K


شاید چند سال پیش خیلی ها از جمله خود من با اصطلاحات HD و FullHD آشنا نبودند ولی در حال حاضر به حدی این فرمت های گشترش پیدا کرده و معمول شده اند که وقتی که میخواهیم یک تلویزیون جدید خریداری کنیم یا ویدئویی را دانلود کنیم ابتدا به سراغ وضوح تصویر آن می رویم و این کاملا هم طبیعی است. فرمت های HD و FullHD ، به مرحله ی اشباه و تکامل خود رسیده اند و شرکت های سازنده ی تلویزیون و نمایشگر مدتی است که به سراغ فرمت های جدید رفته اند و برخی هم محصولاتی را با این فرمت ها وارد بازار کرده اند. البته در کنار آنها، دوربین های حرفه ای جدید نیز از این فرمت ها پشتیبانی می کنند، تا دچار کمبود محتوا برای این تلویزیون ها و نمایشگر ها نشویم!  ( 2K : تفکیک پذیری 1080*2048 برای سینما)  


 اصطلاحات 4K و 8K که این روز ها بیشتر و بیشتر شنیده می شوند، و یا با نام Ultra HD یا UHD بیان می شوند، به رزولوشن یا تفکیک پذیری یا وضوح تصویر جدیدی اطلاق می شود که پس از وضوح تصویر Full HD درحال معمول شدن هستند. اصطلاحا 4K به معنی وجود تقریبا 4000 هزار پیکسل، و 8K وجود 8000 هزار پیکسل فیزیکی در یک ردیف افقی در طول صحفه نمایش؛ و اگر آن را در مورد ویدئو ها به کار ببریم به همین میزان پیکسل افقی، در ویدئو است. تفکیک پذیری دقیق 4K و 8K و در نتیجه تعداد کل پیکسل ها در این دو فرمت به "نسبت تصویر" صفحه یا ویدئو بستگی دارد ولی برای مثال 4K در نسبت تصویر 16:9 برای تلویزیون ها برابر با 3840 x 2160 است که تقریبا دو برابر تفکیک پذیری FullHD برای همین نسبت تصویر است. تصویر بالا فرمت 4K را از نظر اندازه با فرمت های معمول مقایسه کرده است و طبق آن میتوانید به حد و حدود فرمت 8K با 33 میلیون پیکسل پی ببرید!

اگر بخواهیم این فرمت ها را با تعداد پیکسل های عمودی بیان کنیم این چنین خواهد بود :


HD : 720 pixels
FullHD : 1080 pixels
UltraHD-4K : 2160 pixels
UltraHD-8K : 4320 pixels


عملگر های + و - در delegate


عملگر + به نحوی برای delegate سربارگذاری شده است تا لیست توابع دو delegate را در یک شی delegate ترکیب کند. برای مثال کلاس زیر را در نظر بگیرید که دارای دو تابع عضو است.


class HandlerClass
{public:
 static void Func1()
 {
   Console::WriteLine("First function called\n");
 }
 static void Func2()
 {
   Console::WriteLine("Second function called\n");
 }
};


همچنین delegate را به صورت زیر تعریف کرده ایم :

public delegate void HANDLER ();


حالا یک بار delegate را با تابع اول (Func1) تعریف می کنیم و آن را فراخوانی می کنیم.


HANDLER^ handler = gcnew HANDLER (HandlerClass::Func1);
handler();

چون تابع اول تنها تابع در لیست فراخووانی delegate است، خروجی به صورت زیر خواهد بود :

"First function called"

حالا با استفاده از عملگر + تابع دوم را به لیست توابع delegate اضافه می کنیم.

handler += gcnew HANDLER(HandlerClass::Func2);

الان متغیر handler به دلیگیتی اشاره دارد که دو تابع را در لیست توابع خود دارد. البته این دستور یک delegate جدید ایجاد می کند. حالا دوباره آن را فراخوانی می کنیم. 

handler();

حالا این خروجی را خواهید گرفت :

"First function called"
"Second function called"

هر دو تابعی که که در لیست دلیگیت وجود دارند به ترتیبی که در آن قرار گرفته اند فراخوانی می شوند.
عملگر - نیز عملکردی مشابه عملکرد + دارد، البته واضح است که اینبار توابع مشخص شده به صورت ارگومان، از لیست توابع delegate خذف می شوند. برای مثال دستور زیر تابع Func2 را از لیست handler حذف می کند.

handler -= gcnew HANDLER(HandlerClass::Func2);

در برنامه نویسی با فناوری Windows Forms بسیار از این دو عملگر برای ایجاد و به کار گیری Event های مختلف استفاده می شود.

ISOCPP مسئول تدوین استاندارد های C++


C++ زبان بزرگ و مهمی در دنیای کامپیوتر است. همه ما این را می دانیم و به آن معترف هستیم و می دانیم بدون آن شاید دنیای کامپیوتر به شکل امروزی نبود. اکثر قریب به اتفاق زبان های برنامه نویسی جدید از C و C++ تاثیر گرفته اند و دنیای کامپیوتر بر این دو زبان بنا شده است. پس همینگونه که واضح است یکپارچه سازی و ارتقای C++ امری بسیار مهم و بزرگ است، چون هنوز هم بسیاری از شرکت ها به این زبان وابسته اند و روی آن سرمایه گذاری می کنند. امروزه زبان C++ تحت تسلط هیچ شرکتی نیست و استاندارد سازی آن توسط ISO صورت می گیرد. ISOCPP موسسه ای نا سودبر است که جهت تدوین استاندارد های این زبان و ارتقای آن تشکیل شده است و در راس افراد حاضر در آن، خالق این زبان، آقای بیارنه استراستروپ قرار دارد. تا قبل از سال 2011 آخرین استاندارد کلی C++ در سال 1998 به تصویب رسید و از آن موقع به بعد استاندارد دیگری برای این زبان تدوین نگردید، تا در سال 2011 که استاندارد کلی دیگری برای C++ به تصویب رسید و آن را به نام C++11 می شناسیم. به همت ISOCPP دو استاندارد جدید این زبان برای سال 2014 و 2017 برنامه زیری شده اند، که از این دو، استاندارد 2017 ، استاندارد کلی بعدی برای C++ خواهد بود.



از دیگر اهدف ISOCPP ، شفاف سازی و امکان مشارکت علاقه مندان در پروسه تدوین استاندارد است. در سایت ISOCPP.org میتوانید به اطلاعات بسیاری در مورد C++ استاندارد دسترسی داشته باشید شامل آموزش ها، اخبار، ویدئو ها و لینک های مرتبط می شود. بد نیست این را هم بدانید که این بنیان توسط شرکت های بزرگی همچون ماکروسافت، گوگل، اینتل و ... حمایت مالی می شود ولی این شرکت ها حق رای در استاندارد سازی ندارند و صرفا از این بنیان حمایت می کنند، چون منافعشان به زبان C++ وابسته و مرتبط است.  

Delegate چیست ؟ (C++)  


در زبان برنامه نویسی سی پلاس پلاس، Event یک عضو از کلاس است که به یک شی اجازه اطلاع رسانی هنگام رخ دادن اتفاق خاص را می دهد، و علمیات اطلاع رسانی یا سیگنالینگ شامل یک Delegate (نماینده) می شود که امکان عکس العمل به Event را فراهم می آورد. برای مثال یک کلیک موس یک event به حساب می آید و شیئی که از این event سرچشمه می گیرد می تواند با فراخوانی یک یا چند تابع، رخ دادن این event را اطلاع رسانی کند؛ یک delegate میتواند ابزار دسترسی به توابعی که مسئول این event هستند را ارائه کند. 
ایده delegate بسیار ساده است - یک شی که یک یا چند اشاره گر به تابعی که دارای یک لیست پارامتر و نوع خروجی است، را در بر می گیرد. این تابع که delegate به آن اشاره می کند، Event را مدیریت می کند. پس delegate در C++/CLI تقریبا عملکرد مشابهی نسبت به "اشاره گر به تابع" در C++ استاندراد دارد.

تعریف delegate :

تعریف delegate ، مشابه تعریف تابع است که در ابتدای آن از کلمه delegate استفاده شده باشد. اما در اصل دو چیز در آن تعریف می شود: نام نوع ارجاع برای شی delegate و لیست پارامتر ها و نوع خروجی تابعی که می تواند همراه با delegate به کار رود. نوع ارجاع یک delegate ، کلاس System::Delegate را به عنوان کلاس پایه در اختیار دارد، پس همیشه از این کلاس مشتق خواهد شد. در زیر نمونه ای از تعریف delegate آمده است.

public delegate void HANDLER(int value);

این خط یک HANDLER از نوع ارجاع delegate تعریف می کند که نوعش از System::Delegate مشتق شده است و یک شی از آن می تواند حاوی اشاره گری به یک یا چند تابع با یک پارامتر ورودی int و نوع خروجی void (بدون نوع خروجی) داشته باشد. تابعی که delegate به آن اشاره می کند میتواند Static یا Instance باشد.

ایجاد delegate :

حالا که delegate را تعریف کردیم میتوانیم اشیاء delegate از این نوع ایجاد کنیم. ما میتوانیم دو تابع سازنده داشته باشیم که اولی، یک و دیگری، دو پارامتر را می پذیرد. پارامتری که برای سازنده delegate با یک پارامتر استفاده می شود باید یک تابع static عضو کلاس یا یک تابع عمومی باشد. تابعی که به عنوان پارامتر تعریف می کنید باید دارای پارامتر ها و نوع خروجی یکسان با انواع تعریف شده در delegate باشد. برای مثال کلاس زیر را در نظر بگیرید.


class HandlerClass
{public:
static void Sample(int num)
{
  Console::WriteLine(L"Function called with value {0}", num);
}

};

تابع Sample از کلاس بالا را به عنوان تابع مدیریت کننده ی Event به کار می بریم. این تابع دارای یک پارامتر ار نوع int و نوع خروجی void است درست مانند آنچه در delegate تعریف کرده ایم. البته نیازی نیست این تابع در کلاس باشد و هر تابعی متواند این مسئولیت را قبول کند. در زیر از این تابع برای ایجاد delegate استفاده می کنیم.


HANDLER^ handler = gcnew HANDLER (HandlerClass::Sample);


شی handler ، آدرس تابع استاتیک Sample در کلاس HandlerClass را در بردارد. اگر شما delegate را فراخوانی کنید، این تابع را فراخوانی کرده اید. این فراخوانی را می توان به صورت زیر انجام داد.


handler - > Invoke("parameter");

یا به صورت  :

handler ("parameter");

این دستور باعث فراخوانی توابعی می شود که در لیست فراخوانی delegate قرار دارند که در این مثال تنها تابع Sample می باشد. پس خروجی به صورت زیر خواهد بود. (فرض کنید مقدار 100 را به عنوان پارامتر به delegate ارسال کرده ایم)


(عبارت زیر در خروجی چاپ می شود)
Function called with value 100

در پست های بعدی به سراغ ادامه ی بحث delegate در C++ می رویم.
   style=

تغییر حالت Sata از IDE به AHCI پس از نصب ویندوز

 
اگر می خواهید مد پورت Sata مادربورد را از حالت IDE به حالت AHCI تغییر دهید، خوب است بدانید که نیازی نیست دوباره ویندوز کامپیوتر را نصب کنید! خیلی راحت با تنظیماتی ساده در رجیستری ویندوز (که احتمالا به صورت پیشفرض نیز صورت دلخواه ما قرار داده شده است) می توانید حالت پورت ساتا را در تنظیمات بایوس کامپیوتر خود تغییر دهید. برای این کار وارد رجیستری ویندوز شوید و کلید زیر را پیدا کنید. 
(برای وارد شدن به رجیستری ویندوز کلمه regedit را در قسمت Run ویندوز تایپ کنید و Ok را کلیک کنید)


HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\msahci

یا در ویندوز 8 :

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\storahci

پس از اینکه کلید بالا را پیدا کردید کافی است مقدار (ارزش) گزینه ی Start را برابر 0 قرار دهید. برای اینکار بر روی گزینه Start کلیک راست کرده و گزینه ی Modify را انتخاب کنید. سپس در قسمت Value data مقدار 0 را وارد کنید. (همانطور که گفته شد به احتمال زیاد این مقدار، به صورت پیشفرض نیز برابر 0 خواهد بود). کار ما در بخش رجیستری ویندوز تمام است حالا می توانید در قسمت BIOS حالت AHCI را برای پورت ساتا انتخاب کنید. (توجه داشته باشید، شاید ممکن باشد پس از این کار، هارد دیسک یا SSD خود را به عنوان اولین وسیله بوت کامپیوتر انتخاب کنید تا همه چیز به درستی کار کند).

برنامه ماتریس همسازه (C#)


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


private float[,] Kehad (float[,] matrix, int ROW, int COL)
{
int Size = (int) Math.Sqrt(matrix.Length);
float[,] result = new float[Size - 1, Size - 1];
int x = -1, y = 0;
for (int i = 0; i < Size; i++)
{
   if (i == ROW)
   continue;
   x++;
   y = 0;
   for (int j = 0; j < Size; j++)
    {
         if (j == COL)
           continue;

        result[x, y++] = matrix[i, j];
    }
}
return result;
}

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


A i, j = (-1) ᴵ + ᴶ x | M i ,j |

پیاده سازی این فرمول در زبان سی شارپ می تواند به صورت زیر باشد :



private float[,] Hamsaze (float[,] matrix)
{
int Size = (int)Math.Sqrt(matrix.Length);
float[,] result = new float[Size, Size];
for (int i = 0; i < Size; i++)
{
   for (int j = 0; j < Size; j++)
   {
     result[i, j] = (float) Math.Pow(-1, (i+1 + j+1)) * Determinant(Kehad(matrix, i, j));
   }
}
return result;
}

خروجی تابع بالا نیز یک ماتریس از نوع float است و ورودی آن، ماتریس اصلی است. در تابع بالا برای تک تک درایه های ماتریس اصلی همسازه محاسبه می شود و تابع Determinant دتر مینان ماتریس (های) ارسال شده را محاسبه می کند که قبلا در موردش توضیح داده بودیم. برای آزمایش می توانید از برنامه زیر استفاده کنید، البته برای اجرای آن نیاز به فریمورک .Net نسخه 4.5 دارید.




با "کلاس درس" آشنا شوید...

"کلاس درس" (kelasedars.org) سایتی دوست داشتنی و مفید است که توسط چند دبیر، مدیریت می شود و در آن می توانید به ویدئوهای آمورشی مطالب درسی (بیشتر دوره ی دبیرستان) دسترسی داشته باشید که به گفته ی سایت به بیش از 350 عدد می رسد و در حال افزایش است. پس دست در دست هم دهیم به مهر میهن خویش را کنیم آباد...

« مدرسه ای برای همه
آرمان «کلاس درس» که شریک آموزشی «آکادمی خان» در زبان فارسی است، فراهم کردن آموزش رایگان و باکیفیت تمامی یافته‌های علم برای همه‌ی فارسی‌زبانان است. ما قصد داریم به وسیله ویدیوهای کوتاه‌مدت آموزش در بالاترین سطح ممکن را برای همه و به طور یکسان فراهم کنیم. »

پدر زبان سی شارپ، Anders Hejlsberg

Anders Hejlsberg یک برنامه نویس و مهندس نرم افزار برجسته دانمارکی است که در طراحی و توسعه چند زبان برنامه نویسی محبوب و موفق شرکت داشته است. او طراح و خالق زبان توربو پاسکال و طراح ارشد زبان دلفی بوده است و هم اکنون در شرکت ماکروسافت به عنوان طراح ارشد زبان سی شارپ و توسعه دهنده ی زبان TypeScript فعالیت می کند. در سال 2001 جایزه "ممتازی در برنامه نویسی" از مجله Dr. Dobb's به وی اهدا شد. او را به عنوان پدر زبان C# می شناسند.

ماتریس همسازه


در این پست به یادآوری ماتریس همسازه (یا همسازه ماتریس) می پردازیم. همسازه که تنها برای "ماتریس های مربعی" موجود و قابل محاسبه است، به صورت زیر تعریف می شود : (فرض کنید A نام ماتریس ما باشد)


A i, j = (-1) ᴵ + ᴶ x | M i ,j |


منظور از A i, j ، همسازه درایه ی سطر i و ستون j از ماتریس اصلی است که برابر است با -1 به توان i+j ضربدر دترمینان ماتریس کهاد حاصل از حذف سطر i و ستون j از ماتریس اصلی. (البته قبل از آن باید می گفتم که ماتریس کهاد را هم با M نشان می دهیم و M i ,j یعنی ماتریس کهاد حاصل از حذف سطر i ام و ستون j ام ماتریس اصلی).
دقت کنید که از فرمول بالا یک عدد به دست می آید نه یک ماتریس، و آن عدد، i و j اومین همسازه ماتریس A می باشد. پس برای تعیین ماتریس همسازه یک ماتریس مربعی باید برای هر یک از درایه های ماتریس اصلی، فرمول بالا را به کار ببریم و همسازه هر درایه را تعیین کنیم و در جای متناظر قرار دهیم تا ماتریس همسازه به دست آید.

برنامه ی ضرب بولی ماتریس به زبان C++


در پست های قبل برنامه ای برای ضرب دو ماتریس بولی (ماتریس هایی که درایه های آنها تنها 0 و 1 هستند) به زبان C# (سی شارپ) قرار داده بودم که مثل اینکه خیلی مورد علاقه دوستان قرار گرفته بود. در این پست تقریبا برنامه مشابهی به زبان C++/CLI رو در برای شما قرار دادم که می توانید برای "ضرب معمولی ماتریس" و "ضرب بولین ماتریس" به کار ببرید. البته برای استفاده از این برنامه باید فریمورک .Net نسخه ی 4.5 را در کامپیوترتان داشته باشد.

تبدیل صریح یا cast در C++


از دستورات "تبدیل صریح" (explicit conversion) که cast نیز نامیده می شود، برای مجبور کردن کامپایلر به تبدیل انواع در زبان C++ استفاده می شود. انواع مختلفی بز دستور cast وجود دارند که یک به یک به انها می پردازیم. برای شکل دادن مقدار یک عبارت به یک نوع دلخواه به صورت زیر عمل می کنیم.


static_cast < "new type" > ("old type" or "expression");

کلمه ی static_cast در بیان می کند که cast به صورت ایستا یا static بررسی خواهد شد. به این معنی که هنگامی که برنامه ی شما کامپایل شد، دیگر در هنگام اجرا، بررسی نخواهد شد که آیا این دستور cast برای اعمال مطمئن هست یا خیر. نتیجه این دستور، تبدیل متغیر یا نتیجه ی یک عبارت (عبارت کوتاه و ساده یا عبارت پیچیده) به نوع اعلام شده در داخل علامت < > می باشد. 
در هنگام کار با کلاس ها با dynamic_cast کار خواهید کرد، که در آن تبدیلات به صورت پویا یا dynamic (در حال اجرای برنامه) بررسی و چک خواهند شد.
نوع بعدی تبدیل صریح، const_cast نام دارد که برای از بین بردن "ثابت بودن" یک ثابت یا یک عبارت به کار می رود.
reinterpret_cast و safe_cast نیز انواع دیگری از این دستورات هستند که در پست های بعدی به سراغ آنها می رویم.

وراثت در C++ (مقدمات)


در زبان برنامه نویسی C++ هنگامی که کلاسی را بر اساس کلاس موجود دیگری تعریف می کنید، به کلاس جدید، "کلاس وارث" یا به انگلیسی Derived Class و به کلاس اولیه، "کلاس پایه" یا Base Class گفته می شود. کلاس های وارث به طور خودکار داری تمام داده ها و (با کمی محدودیت) تمام توابع عضو کلاس پایه هستند و به قول معروف این اعضا را به ارث می برند. البته کلاس پایه نیز همچنان دارای این اعضا خواهد بود و کلاس پایه هم می تواند علاوه بر این اعضا دارای اعضای اختصاصی خود باشد.
توابعی که از کلاس پایه برای کلاس وارث، اختصاص نمیابد، "توابع سازنده"، "تابع نابودگر" و توابعی هستند که عملگر جایگزینی ( = ) را سربارگذاری می کنند. دلیل آن هم این است که هر کلاس دارای توابع سازنده و نابودگر خاص خود است. برای مثال تمامی کلاس هایی که در محیط دات نت (تحت CLR ) تعریف می کنید به طور خودکار وارثی از کلاس Base Object Class هستند حال انکه بخواهید اینطور باشد یا نه؛ و البته همین کلاس ها نیز می توانند کلاس پایه برای کلاس های دیگر باشند.
نحوه ی تعریف یک کلاس وارث مشابه کلاس های دیگر است و تنها تفاوت ان با یک پلاس معمولی مجزا در این است که پس از نام آن، نام کلاس پایه ذکر می شود. در زیر مثالی ساده برای این مورد آورد شده است.


کلاس پایه :

class parent
{public:
  bool flag;
  string str;
}

کلاس وارث :

class child : parent
{public:
  float f;
  short int si;
}

در بالا، parent یک کلاس پایه و child یک کلاس وارث می باشد. به این معنی که داده های عضو کلاس parent (که شامل str و flag هستند) برای کلاس child نیز قابل استفاده هستند. برای مثال می توان به صورت زیر به متغیر عضو flag در کلاس دسترسی پیدا کرد.


child obj;
obj.flag = true;

البته نه به همین سرعت ! باید دقت داشته باشید "وراثت" به طور پیشفرض به صورت "خصوصی" یا private صورت میگیرد و هنگامی که وراثت به صورت خصوصی تعریف شود نمی توان به داده های عضو به ارث گذاشته شده، در خارج از کلاس دسترسی پیدا کرد و اگر بخواهید دستور بالا را به کار ببرید با خطای کامپایلر موجه خواهید شد که جمله ی بالا را به شما می گوید! برای تعریف وراثت کلاس به صورت "عمومی" یا public تنها کافی است قبل از نام کلاس پایه، کلمه ی public را اضافه کنید تا بتونید به اعضای داده ی به ارث گذاشته شده، در خارج از کلاس دسترسی داشته باشید.


class child : public parent;    

افزودن یک ستون به DataGridView (به صورت هوشمند)

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

اضافه کردن یک سطر :
DataGridView_Name.Rows.Add();
اضافه کردن یک ستون :
DataGridView_Name.Columns.Add("Column_Name", "Header_Name");


حالا اگر بخواهیم وقتی که کاربر یکی از سلول های های ستون آخر را پر کرد یک ستون به DataGridView اضافه شود می توانیم از یک Event به نام CellBeginEdit استفاده کنیم. برای این کار باید یک Event در قسمت Form Designer پروژه به DataGridView خود اضافه کنید و یک تابع برای اضافه کردن ستون ایجاد کنید. در زیر مثالی از هر دو آورده شده است :

تعریف Event :

this.dataGridView_Name.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.AutoAddColumn);


تعریف تابع AutoAddColumn :

private void AutoAddColumn(object sender, EventArgs e)
{
   // add a column to datagrid
   if (dataGridView_Name.CurrentCell.ColumnIndex == dataGridView_Name.ColumnCount - 1)
   {
      DataGridView_Name.Columns.Add("Column_Name", "Header_Name");
   }
}

با استفاده از CellBeginEdit ، هنگامی که یک سلول ویرایش می شود تابع AutoAddColumn اجرا می شود و اگر این سلول جزء سلول های آخرین ستون DataGridView باشد، با استفاده از تابع Add یک ستون به ستون های موجود آن اضافه می شود.