20 Mayıs 2016 Cuma

-C++ Tür Dönüştürme(Casting)-

Merhabalar,
Bu yazıda C++'da tür dönüştürme işleçlerini inceleyeceğiz. Fakat tür dönüştürmenin ne olduğu ile ilgili
temel bilgi verilmeyecektir.

C++'da beş adet tür dönüştürme işleçi vardır.Bunlar:
- Standart C'den kalan yöntem.
- static_cast
- const_cast
- dynamic_cast
- reinterpret_cast

Tür dönüştürme işlemlerine standart C yöntemiyle başlayacağız. Ancak C++ derleyicileri ayrıca otomatik olarak tür dönüştürme işlemleri gerçekleştirir. Dolayısıyla derleyiciye göre C++'de tür dönüştürme işleçleri,yukarıda yer verilen sayıdan farklılık gösterebilir. Derleyicinin sahip olduğu işleçlere değinilmeyecektir.

Standart C'den kalan yöntemin kullanımına aşağıda yer verilmiştir:

int sayi = 10.0;
double d = (double) sayi;

Standart yöntem gayet sade bir yapıya sahiptir. Ancak bu yöntemin kullanılması önerilmez.
Çünkü C++ derleyicisi bu kullanımda programcıya hiçbir şekilde katkı sağlamaz.
Dolayısıyla hatalı kullanım ve/veya uyarı durumlarda derleyici sessiz kalacaktır.

C++'da tür dönüştürme işlemi daha detaylı bir yapıya sahiptir. Yani birçok amaca uygun tür dönüştürme yöntemleri mevcuttur.

-static_cast:
Bu yöntem,isminden de anlaşıldığı gibi dinamik sözkonusu olmayan durumlarda kullanılır. Yani çalışma zamanı esnasında,dönüştürme işlemine tabi tutulan tür'den emin olmayı gerektirir.
Dolayısıyla derleme zamanında bilinen tür dönüşümlerde bu yapı kullanılabilir.
static_cast kullanımını gösteren bir uygulamaya aşağıda yer verilmiştir.
Örnek:
#include <iostream>
#include <typeinfo>

using namespace std;

class Model
{
public:
Model()
{
//
}
~Model()
{//...
}

};

class BMW : public Model
{
public:
void modelIsmi()
{
cout << "BMW" << endl;
}

};

class Mercedes : public Model
{
public:
  void modelIsmi()
{
cout << "Mercedes" << endl;
}
};

int main()
{
  Model *model1 = new Model();
  Model *model2 = new Model();
  
  BMW *model3 = static_cast<BMW*>(model1);
  model3->modelIsmi();
  
  Mercedes *model4 = static_cast<Mercedes*>(model2);
  model4->modelIsmi();

 return 0;
}



-const_cast:
const olarak tanımlanmış bir değişken,const olarak tanımlanmamış bir başka değişkene atanamaz.
Dolayısıyla aşağıda verilen örnekte hata meydana gelecektir.
Örnek:
const char* text = "Kerim FIRAT";
char *veri2 = text;

Ancak "const" tanımlı bir türü manipüle etmek için "const_cast" tür dönüştürme yapısı kullanılabilir.
Yani bu yapı "const" olarak tanımlanmış türler üzerinden kullanılır.
Aşağıda bu örneğe yer verilmiştir.
Örnek:

const char *text = "Kerim FIRAT";
char *text2 = const_cast<char*>(text);
cout << text2 << endl;



-dynamic_cast:
Bu dönüştürme yöntemi referans ve göstericiler(pointer) de kullanılır.
Dönüştürme işlemi başarısız olması durumunda geri dönüş değeri "NULL" olur.
Ayrıca üst sınıfta enaz bir adet "virtual" fonksiyon bulundurmak zorunludur.
Örnek:
using namespace std;

class Model
{
public:
Model()
{
//
}
virtual void modelIsmi()
{
}

~Model()
{//...
}
 };

class BMW : public Model
{
public:
virtual void modelIsmi()
{
cout << "BMW" << endl;
}

};

class Mercedes : public Model
{
public:
  virtual void modelIsmi()
{
cout << "Mercedes" << endl;
}
};

int main()
{

  Model *model1 = new Model();
  Model *model2 = new Mercedes();

  Model *model3;
  
  model3 = dynamic_cast<BMW*>(model1);
  if(model3 !=NULL)
  {
model3->modelIsmi();
  }else{
cout << "model3 BMW'ye dönüştürme hatalı.!" << endl;
  }

  model3 = dynamic_cast<Mercedes*>(model2);
  if(model3 !=NULL)
  {
 model3->modelIsmi();
  }else{
 cout << "model3 Mercedes'ye dönüştürme hatalı.!" << endl;
  }
   
 return 0;
}

Çıktı:
model3 BMW'ye dönüştürme hatalı.!
Mercedes


-reinterpret_cast:
Tür dönüştürme yapılarında en esnek çalışan yapı budur.
Bu yapıyla,her türden gösterici(pointer)'i her türlü gösterici türüne çevirebiliriz.
Bukadar esnek olmasındaki sebep ise aslında bit taşıyor olmasından kaynaklanıyor.
Yani dönüştürülecek nesnenin bit yapısını diğer nesneye kopyalar. 
Ancak kullanırken dikkatli olmalısınız. Esnek olması tüm türleri hatasız dönüştürecek diye bir anlam oluşturmaz.
Kullanım örneğine aşağıda yer verilmiştir.

int main()
{
int sayi = 44;
unsigned int *unsint = reinterpret_cast<unsigned int*>(&sayi);
cout << *unsint << endl;

    Model *model1 = new Model();
    Model *model2 = new Mercedes();
    
     BMW *model3;
     model3 = reinterpret_cast<BMW*>(model1);
     model3->modelIsmi();
     
     Mercedes *model4;
     model4 = reinterpret_cast<Mercedes*>(model2);
     model4->modelIsmi();
  return 0;
}

İyi çalışmalar..

Hiç yorum yok:

Yorum Gönder