Tuesday, December 30, 2014

C++ / Template anahtar kelimesi kullanımı ve taslak sınıf, yapı ve fonksiyon yaratımı


Evet, başlıktan anlaşıldığı üzere konumuz template, yani taslak obje ve fonksiyonlar.

Template sınıflar ve yapılar, herhangi bir sınıfı, farklı değişken tipleri ile bir arada kullanmak istediğimizde yardımımıza yetişiyor.

Aşağıdaki sınıfı örnek alalım;



#pragma once
#include <vector>

using namespace std;

class TemplateExample
{

public:
 bool insert_data(int value)
 {
  storage.push_back(value);
  return true;
 }

 bool remove_data(int value)
 {
  bool found = false;
  int i = 0;
  for (const auto v : storage)
  {
   if (v == value)
   {
    found = true;
    break;
   }
   i++;
  }

  if (found)
  {
   storage.erase(storage.begin() + i);
   return true;
  }
  return false;
 }

 std::vector<int> getStorage(){ return storage; }
private:
 std::vector<int> storage;

};




Farkettiğiniz üzere sınıf bir tamsayı vektörü ve üç fonksiyondan oluşan basit bir depolama sınıfı. Sınıfın kullanımı şu şekilde olacaktır;

#include "stdafx.h"
#include "TemplateExample.h"
#include <iostream>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 TemplateExample te;
 te.insert_data(1);
 te.insert_data(2);
 te.insert_data(3);

 te.remove_data(2);

 for (const auto v : te.getStorage())
  cout << v << endl;

 cin.ignore();
 return 0;
}




Buraya kadar bir sıkıntımız yok. Şimdi farzedelim ki, programımız aynı zamanda string ve char değerlerini depolayan sınıflara da ihtiyaç duyacak. Bu durumda ne yapmamız gerekir? Yukardaki sınıfı kopyalayıp değişken tipini değiştirmeyi düşündüyseniz, hiç zahmet etmeyin. Template anahtar kelimesi burada devreye giriyor. Yukardaki sınıfımızda yapacağımız ufak bir değişiklik, sınıfımızın bütün değişken tipleri ile uyumlu hale gelmesini sağlayacak.

template<typename T>
class TemplateExample
{

public:
 bool insert_data(T value)
 {
  storage.push_back(value);
  return true;
 }

 bool remove_data(T value)
 {
  bool found = false;
  int i = 0;
  for (const auto v : storage)
  {
   if (v == value)
   {
    found = true;
    break;
   }
   i++;
  }

  if (found)
  {
   storage.erase(storage.begin() + i);
   return true;
  }
  return false;
 }

 std::vector<T> getStorage(){ return storage; }
private:
 std::vector<T> storage;

};





Gördüğünüz üzere, kod ilk verdiğim örnekteki sınıfın neredeyse aynısı, sadece ufak bir fark var; "template". Ve değişken adlarının yerini T harfi almış. Peki bu ne anlama geliyor?

Sınıfımızın üzerinde yazan template<typename T> satırı, sınıfımızın bir generik taslak olduğunu belirtiyor ve sınıfımızı yaratırken T değişken tipine atayacağınız değeri otomatikman bütün sınıfa uyguluyor.

Template sınıfları yaratırken, normal sınıflardan farklı olarak yanına değişken tipi de ekleriz;</pre>
Normal;
      TemplateClass normal;
Template;
      TemplateClass<char> template;

<> işareti arasında vereceğimiz değişken tipi, sınıfımızın içerisindeki bütün T'lerin yerine geçiyor. Dolayısıyla, başımız ağrımadan bütün değişken tiplerine uyumlu bir depolama sınıfı elde etmiş oluyoruz.

Kullanım;

#include "stdafx.h"
#include "TemplateExample.h"
#include <iostream>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{

 // Tamsayı (integer)
 TemplateExample<int> tamsayiDepolama;
 tamsayiDepolama.insert_data(1);
 tamsayiDepolama.insert_data(2);
 tamsayiDepolama.insert_data(3);

 tamsayiDepolama.remove_data(2);

 for (const auto v : tamsayiDepolama.getStorage())
  cout << v << endl;

 // Karakter(char)
 TemplateExample<char> charDepolama;

 charDepolama.insert_data('a');
 charDepolama.insert_data('b');
 charDepolama.insert_data('c');

 charDepolama.remove_data('b');

 for (const auto v : charDepolama.getStorage())
  cout << v << endl;

 // Yazı (string)
 TemplateExample<std::string> stringDepolama;

 stringDepolama.insert_data("this");
 stringDepolama.insert_data("is");
 stringDepolama.insert_data("sparta!");

 stringDepolama.remove_data("is");

 
 for (const auto v : stringDepolama.getStorage())
  cout << v.c_str() << endl;

 cin.ignore();
 return 0;
}



Template anahtar kelimesi, yalnızca struct ve classlara özgü değildir. Aynı zamanda fonksiyon tanımlamalarınızda da bu anahtar kelimeyi kullanabilirsiniz.

Örnek olarak ;




template<typename T>
void TemplateFonksiyon(T val)
{
 return;
}
Fonksiyonu çağıralım;
TemplateFonksiyon<int>(1);
Bugün kod hayatınızı bir nebze olsun kolaylaştıracak yeni bir keyword öğrendiniz. Tadını çıkarın ve ihtiyacınız olan her yerde bunu kullanın! Sağlıcakla kalın :)
Mustafa K. Bilgisayar Müh.

Kahve kokusu, visual studio, uykusuzluk ve huzur.

No comments:

Post a Comment