2. • Öncelikle bu konu orijinal C++ tanımlaması değildir ve birkaç
sene önce bulunmuştur.
• Gerçekte derleyici template ile verilmiş fonksiyon gövdesi için
herhangi bir kod üretmez. Çünkü template ile bazı verilerin tipi
parametrik olarak ifade edilmiştir. Verinin tipi ancak bu fonksiyona
ilişkin bir çağrı olduğunda ortaya çıkacaktır. Derleyici her farklı tip
için yeni bir fonksiyon oluşturacaktır. template yeni fonksiyonun
verinin tipine bağlı olarak nasıl oluşturulacağını tanımlamaktadır.
•Programı ister template yapısı ile oluşturalım ister de template
yapısı olmaksızın oluşturalım, programın bellekte kaplayacağı
alan değişmeyecektir.
•Değişen, kaynak kodun boyu olacaktır. template yapısı
kullanılarak oluşturulan programın kaynak kodu, daha anlaşılır ve
hata denetimi daha yüksek olacaktır. Çünkü template yapısı
kullanıldığında değişiklik sadece tek bir fonksiyon gövdesinde
yapılacaktır.
3. • Soysal fonksiyonlar bize daha çok pratiklik ve kolaylık kazandırır.
• Soysal fonksiyonlarda en temel ve bilinmesi gereken
nokta, işlenilen verinin tipi parametre olarak döndürülür.
Örneğin,
Bir fonksiyon yazdığımızı düşünelim. Ve bu fonksiyon parametre olarak
bir tamsayı değeri döndürsün. Peki aynı fonksiyonun ondalık olanına da
ihtiyacımız olduğunda ne yapacağız? Bütün fonksiyonu tekrar baştan mı
yazacağız?
İşte tam bu noktada soysal fonksiyonlar yardımımıza koşuyor. Aynı
fonksiyonu hem tamsayı hem de ondalık olarak işletebilecek bir yapı
olduğundan, tekrar tekrar kod yazmamızı engelleyip anlaşılır ve
okunabilir bir kod yazmamızı sağlıyor.
• C++’ta şablonların özelliği ve artısı kaynak kodların tekrar tekrar
kullanılmasıdır. Şablonları kullanarak soysal fonksiyonlar
(fonksiyon şablonları) ve sınıflar oluşturulabilir.
4. • Soysal fonksiyonların avantajları;
* Kod kalabalığından kurtuluruz
* Hata oluştuğunda çok kısa sürede çözüm
bulabiliriz.
* Programın fazladan yer kaplamasını önleriz.
* Fonksiyon ailelerini gereksiz yere çağırmamız
engellenir.
template <class type> dondur_tipi fonksiyon_adi (girilen parametreler)
{
//Kod Bloğu
}
Derleyiciye fonksiyon şablonu tanımlamak üzere olduğumuzu bildirir.
Fonksiyon içerisinde kullanılacak verinin tipini bildirir. “class” kelimesi
yerine “typename” anahtar kelimesi de kullanılabilir.
5. Örneğin,
Girilen int ve float tipindeki değerlerin mutlak değerini alan fonksiyonu
yazınız.
Eski yöntemle:
Template Kullanarak:
int mutlak ( int a)
{
if(a<0) {
return -a;
}
else {
return a
}
}
float mutlak ( float a)
{
if(a<0) {
return -a;
}
else {
return a
}
}
template <class type> int mutlak (type a)
{
if (a<0) {
return -a;
}
else {
return a;
}
}
6. Örneğin,
Programda 4 farklı tip için (int, double, string ve boolean) değeri ekrana
yazan bir fonksiyon şablonu yazınız.
#include <cstdlib>
#include <iostream>
using namespace std;
template <typename T> void yaz (T deger)
{
cout << "deger: "<<deger<<endl;
}
int main()
{
int i=14;
double d=9.91;
string s("Mehmet Yakut");
bool b=true;
yaz(i);
yaz(d);
yaz(s);
yaz(b);
system("PAUSE");
return EXIT_SUCCESS;
}
7. Örneğin,
Bir yığın içerisinde bulunan hem int hem de string tipinde verileri kullanarak
bir sınıf şablonu yazınız.
#include <iostream>
#include <string>
using namespace std;
template <class T>
class yigin
{
public:
yigin();
void ata(T i);
T cek();
private:
int top;
T st[100];
};
template <class T>
yigin<T>::yigin()
{ top = -1; }
template <class T>
void yigin<T>::ata(T i)
{ st[++top] = i; }
template <class T>
T yigin<T>::cek()
{ return st[top--]; }
int main ()
{
yigin<int> int_yigin;
yigin<string> str_yigin;
int_yigin.ata(10);
str_yigin.ata("ibrahim");
str_yigin.ata("Kizir");
cout << int_yigin.cek() << endl;
cout << str_yigin.cek() << endl;
cout << str_yigin.cek() << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
8. • Çoklu şablon argümanları yardımıyla tek şablondan oldukça fazla
fonksiyon oluşturulabilmektedir.
• Eğer fonksiyonlar büyükse çok büyük hafıza kullanımı söz konusu
olur. Ancak çağırmadığımız sürece fonksiyonların örnekleri
oluşturulmaz.
Neden makroları kullanmıyoruz?
abs() fonksiyonu için;
#define abs(n)( (n<0) ? (-n) : (n) )
Şeklinde makro tanımlaması yapabiliriz. Bu kendi içerisinde bir çok problem
barındırmaktadır:
•Bunlardan ilki; tip kontrolü yapmamasıdır. Makro için aynı tipte olan birden
fazla argüman olabilir. Fakat derleyici bunların istenilen tipte olup olmadığını
kontrol etmez.
•İkincisi; dönüş tipi belirtilmemiştir, dolayısıyla derleyici uyun olmayan bir
atama işlemi yapılıp yapılmadığı hakkında bir şey söyleyemez.
Dolayısıyla makro kullanılmasından kaçınılması gerekmektedir.
Örneğin,
9. Örneğin,
Aynı template ifadesi içerisinde double, char, int, long gibi veri tiplerini
kullanan çoklu sınıf şablon örneği yazınız.
#include <iostream>
#include <string>
using namespace std;
template <class tip1, class tip2>
void fonksiyon(tip1 a, tip2 b)
{
cout << a << ' ' << b << endl;
}
int main()
{
fonksiyon(23.6, "derece");
fonksiyon(10, 344000000L);
system("PAUSE");
return EXIT_SUCCESS;
}