یکی از امکانات جالب و مفید زبان ++C قالبها (Templates) هستند که انعطاف زیادی به کدنویسی میدهند.
فرض کنید در یک برنامه نیاز به تعویض مقادیر دو متغیر هست. یعنی مثلا میخواهیم مقادیر a و b را با هم عوض کنیم. اگر a و b از نوع صحیح باشند، تابع جابجایی میتواند به این صورت باشد:
کد:
void swap( int &a, int &b )
{
int temp;
temp = a;
a = b;
b = temp;
}
حال اگر بخواهیم مقادیر دو تا متغیر اعشاری را عوض کنیم، تابع فوق به کار نمیآید و باید تابع جدیدی بنویسیم. اما اگر از قالب استفاده کنیم، همه مشکلات حل میشوند.
به قطعه کد زیر توجه کنید:
کد:
template< class T >
void swap( T &a, T &b )
{
T Temp;
Temp = a;
a = b;
b = Temp;
}
این کد روش استفاده از قالب را نشان میدهد. وقتی کامپایلر به این قطعه کد میرسد، متوجه میشود که یک تعریف کلی از یک تابع ارائه شده است. به جای T میتوان در زمان فراخوانی تابع، هر نوع داده استاندارد، ساختمان یا کلاس استفاده کرد. به عنوان مثال:
کد:
int n = 5, m = 6;
double x = 0.12, y = 125.6;
char a = 'A', b = 'B';
swap( n, m );
swap( x, y );
swap( a, b );
cout << " n = " << n << ", m = " << m << endl;
cout << " x = " << x << ", y = " << y << endl;
cout << " a = " << a << ", b = " << b << endl;
خروجی:
کد:
n = 6, m = 5
x = 125.6, y = 0.12
a = B, b = A
به عبارت سادهتر، وقتی کامپایلر به کد
swap( n, m )
میرسد، متوجه میشود که باید T را int در نظر بگیرد و ...
همانطور که گفته شد، میتوانید برای اشیاء کلاسها و ساختمانها هم از قالب استفاده کنید. اگر strval1 و strval2 دو متغیر از نوع ساختمان دلخواه باشند، عبارت
کد:
swap( strval1, strval2 )
کاملا درست بوده و باعث جابجایی متغیرهای متناظر ساختمانها میشود.
قالبها از تمامی امکانات ++C نظیر سربارگزاری، تعریف مجدد و پارامترهای پیشفرض پشتیبانی میکند. مهمتر از همه این که میتوان از قالبها برای تعریف کلاسها استفاده کرد:
کد:
template< class T >
class myclass
{
private:
T a;
public:
myclass( T x )
{
set_a( x );
}
T get_a( )
{
return a;
}
void set_a( T x )
{
a = x;
}
};
با توجه به تعریف فوق، برای مشخص کردن اشیاء میتوان نوشت:
کد:
myclass<int> n( 7 );
myclass<float> d( 10.5 );
توجه داشته باشید که لازم نیست همه متغیرها از نوع کلی باشند. تابع زیر را در نظر بگیرید که یک آرایه و تعداد اعضای آن را دریافت کرده و این اعضا را چاپ میکند:
کد:
template< class T >
void print( T *arr, int n )
{
int i;
for ( i = 0 ; i < n ; i ++ )
{
cout << *( arr + i ) << endl;
}
}
در ضمن میتوان به جای یک نوع کلی، از چند نوع استفاده کرد:
کد:
template< class type1, class type2, . . . , class typeN >