C++ Class Template


در مورد template ها در گذشته صحبت کردیم و استفاده از انها در توابع توضیح داده شد، حالا در این پست در مورد آوردن این ویژگی به کلاس ها توضیح می دهیم. استفاده از کلاس های template انعطاف پذیری کلاس را افزایش و کد نویسی را کاهش می دهد. در زیر با ارائه یک مثال، پیاده سازی کلی یک کلاس template را نشان می دهیم.


template < class T >
class Class_Name
{
public:
Class_Name (T "Variable_Name")
{
   // code
}
T test (T "Variable_Name")
{
   // code
}
private:
T "Variable_Name";
};

در بالا یک کلاس به صورت template تعریف کرده ایم که یک "سازنده" و یک تابع عضو دارد. قبل از هر چیز توضیح چند چیز ضروری است.
T در مثال بالا تنها یک نام است و هیچ گونه مشکلی برای تعریف نام دلخواه خود نخواهید داشت. T در واقع یک TypeName است (یک "نوع" است) است که در اینده، هنگام ایجاد یک شی از این کلاس تعریف خواهد شد.
مثال بالا تنها نمونه ساده ای از تعریف یک کلاس template است و هیچ مانعی برای برای ایجاد دهها سازنده، تابع و متغیر عضو با استفاده از نوع T وجود ندارد و همچنین مانعی برای تعریف یک کلاس با چندین TypeName نیست. برای مثال می توانید کلاس را با سه typename تعریف کنید که در هنگام ایجاد شی از کلاس به ترتیب، تعریف خواهند شد.

template < class T, class T2, class T3 >

سه نوع T ، T2 و T3 میتوانند در هر کجای کلاس به کار روند و متغیر هایی از نوع آنها تعریف کرد. البته واضح است که کلاس های مدیریت شده نمی توانند متغیر های مدیریت نشده داشته باشند، پس باید در باره ی انتخاب انواع اندیشید.

ایجاد یک شی از کلاس : همانطور که تعریف و قوانین کلاس بالا، مشابه کلاس های معمولی است، تعریف یک شیاز کلاس نیز مشابه کلاس های معمولی است با این تفاوت که باید Type Name هایی که در template تعریف کرده اید را هنگام ایجاد شی از کلاس، مشخص کنید. در زیر حالت کلی تعریف یک شی از کلاس آمده است :


Class_Name < type > Object_Name;

یا (به صورت یک اشاره گر) :

Class_Name < type > * Object_Name = new Class_Name < type > () ;


اگر کلاس شما حاوی چند type name باشد، باید آنها را به ترتیب مشخص کنید.

Class_Name < type1, type2, type3 , ... > Object_Name;

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

template < class T >
Class_Name < T >::Function_Name (T "Variable_Name", other variables...)
{
// code
}

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

در زیر هم نمونه یک template class را مشاهد می کنید که دارای چند تابع عضو و سازنده و type name است.

template < class T, class T2, class T3 > 
class Sample
{
public:
Sample ()
{
// code
}
Sample (T ipt)
{
// code
}
~Sample()
{
// code
}
// Function declaration
void someFunc ();

T somFunc2 (T r)
{
return r;
}
private:
T j;
T2 k;
T someFunc3 (T3 p)
{
// code
}
};

Properties در C++/CLI و C#


اگر برنامه نویس زبان های C++ یا C# هستید حتما با "مشخصات" یا properties کلاس ها کار کرده اید. چه هنگام استفاده از کلاس های از پیش نوشته شده .Net یا کلاس هایی که خود مینویسید. حداقل از field ها استفاده کرده اید. برنامه نویسی بدون استفاده از آنها محال است! field ها همان متغیر های کلاس شما هستند که وقتی به صورت "عمومی یا Public آنها را تعریف می کنید به مشابه (نه دقیقا) مشخصات (Properties) رفتار می کنند. استفاده از فیلد ها و property ها بسیار حیاتی و اساسی است. چطور میشود که یک فایل یا آرایه در اختیار داشته باشید و نخواهید نام، طول یا حجمش را بدانید؟ یا چطور میشود یک مشتری داشته باشید در صورتی که نام، آدرس یا شماره تلفن آو را ندانید ؟ property ها همانطور که از نامشان برمیآید خواص یک شیء هستند و در مورد آن شیء توضیح می دهند.

در این پست کمی بیشتر با Properties در زبان C# یا C++ آشنا می شویم. مثال های این پست به زبان C# هستند ولی در زبان C++/CLI نیز نحو تقریبا مشابه است. حالت کلی تعریف یک property به شکل زیر است :


public/private TYPE Property_Name
{
   get
   {
      // Code
   }

   set
   {
      // code 
   }
}



public" و "private نوع دسترسی به property را مشخص می کنند. "TYPE" نوع property و "Property_Name" واضخا نام آن است. در داخل بلوک اصلی دو بلوک به نام های Set و Get وجود دارد که به setter (قرار دهنده) و Getter (گیرنده) معروف هستند.
کد های بلوک Get هنگامی که کاربر قصد دریافت اطلاعات Property را دارد، اجرا می شوند. و کد های بلوک Set برای ثبت تغییرات و نوشتن در Property به کار می رود. این کد ها میتوانند هر چیزی باشند. از یک عملیات انتصاب ساده تا محاسبات پیچیده... که واضحا بستگی به نیاز شما دارد. اگر property شما نیازی به دستکاری شدن ندارد میتوانید کل بلوک Set را حذف کنید. در این صورت property شما "فقط خواندنی" یا read-only خواهد بود. مسلما برخی از مشخصاتی که در طول برنامه نویسی به آنها سر و کار داریم هم باید این گونه باشند. معمولا در بلوک Get با استفاده از دستور return مقداری که قرار است به برنامه بازگشت داده شود، را بازمیگردانند و در بلوک Set ، عملیات انتصاب عنوان می شود. ولی بسته به نیاز شما هر کدی میتواند در آنها استفاده شود.
پس کلا هدف این کارها چه بوده است ؟ property ها نقش دریافت کننده و فرستنده ی مقادیر را دارند. در setter مقادیر را دریافت می کنید و عملیات دلخواه را روی آنها انجام می دهید و در getter انها را به برنامه برمیگردانید. معمولا property ها به صورت "عمومی" (public) تعریف می شوند (تا توسط کاربر کلاس قابل دسترسی باشند) و مقادیر خود را در فیلد های خصوصی ذخیره می کنند. برخی از مواقع شاید این کار مزیتی نداشته باشد و کار به صورت مستقیم با فیلد ها هم کارتان را راه بیندازد؛ ولی در بسیاری از مواقع، استفاده از property ها مزایای خود را نمایان می کند. مانند پنهان سازی اطلاعات. در اخر می توان property ها را در یک جمله تعریف کرد : "راهی برای درسترسی به اطلاعات." شاید تا همین جا برای این پست کافی باشد، در پست های بعدی به جزئیات در مورد مشخصات کلاس اشاره می کنیم.