Tuesday, January 16, 2007

Convert Constructor

Bircogunuz başlığa bakınca convert constructor mı o da ne diyordur herhalde, aslında convert constructor C++ da bildiğimiz içerisine parametre alan constructor a denmektedir. Peki sizce neden böyle bir ad konulma gereği duyulmuş bu parametre alan constructor tipine? sadece constructor denseydi parametre almayan constructordan nasıl ayrılacaktı... peki böyle bir ayrıma ihtiyaç var mı? peki copy constructor var bide o ne? etrafta bu kadar constructor dolanırken neden bir tanecik destructor var:) Bu soruların cevabını merak ediyorsanız bu yazımı okuyabilirsiniz, merak etmiyorsanız bir aşağıdaki yazıya alalım sizi:)

Şimdi siz aşağıda ki kodu bir inceleyin ve bu kodun çalışıp çalışmayacağını kendinize söyleyin ( Bu şekilde sorduğuma göre kodun çalışmasını bekliyorsunuzdur herhalde :) )

#include<iostream>
using namespace std;


class Test{

int var;

public:

Test( int v = 0 ) : var( v ) {}

int getVar() const { return this->var; }
};


void function( Test t1 ){

cout << t1.getVar()<< endl;

}


int main(){

function( 50 );

return 0;
}


Evet gelelim cevaba. Bu kodun çalışacağını söyleyenler malasef kaybeden tarafta yer almıycaklar:) evet çalışır bu kod. Peki;

gördüğünüz üzere function fonksyonunun giriş parametresi class Test tipinden tanımlanmıştır. Ozaman demek ki bizim function fonksiyonuna Test nesnesi vermemiz gerekir. Oysa biz napıyoruz açıkça bir int parametre veriyoruz...

İşte burada convert constructor dediğimiz olay devreye giriyor! 50 sayısı Test için yazdığımız constructora yada birden fazla varsa sırayla, verilerek Test nesnesine cast edilmeye yani 50 sayısı ile bir giriş parametresi oluşturulmaya çalışılıyor...

Burada argümanlar bire bir uyuştuğu için, Test sınıfının constructor ı bir tane int parametre alır, bu casting işi başarılı oluyor ve Yığında bir adet Test nesnesi oluşturuluyor. Bu yüzden bu constructorlar convert constructor olarak adlandırılmıştır.

Peki gelelim bu durumu engellemek için yapılabileceklere. Bazen böyle bir durumun gerçekleşmesini istemeyebiliriz. Fonksiyonun sadece bir nesneyi direk olarak vererek çalışmasını istediğimiz zamanlar olabilir. Bunu engellemek için ben 3 tane yol önerecem sizin aklına gelirse commentleyin lütfen:)

1) Fonksyionun giriş parametresini referance yapalım. Yani:
void function( Test& t1 ); şeklinde tanımlarsak, yığında nesne oluşturmak işe yaramayacaktır. Çünkü t1 nesnesi direk nesnenin kendisi olmalıdır ( kopyası değil! ) Bu yüzden bu şekilde bir fonksyon için function( 50 ); çağrısı hata verecektir.

2) Hiç convert constructor yazmayalım.. Bu mümkün bir çözüm olmasına rağmen akıldan uzaktır. 3. yöntem e bakın siz:)

3) explicit anahtar sözcüğünü kullanırsak derleyiciye function( 50 ); çağrısının mümkün olamayacağını söylemiş oluruz.
Peki nedir bu explicit? eğer bir convert constructor ı explicit olarak yazarsak, bu constructorın dışarıdan dolaylı olarak nesne üretmesini engellemiş oluruz. Yani function( 50 ); çağrısında ki 50 değeri bu constructor a giremez.

explicit Test( int v=0 ) : var( v ) {}


Evet işte convert constructlar hakkında kısaca söyleceğim şeyler bunlardı. convert constructorlardan başka bir de copy contructorlar var. copy constructor lar ise, bir nesneden bir nesne üretilceği zaman çalıştırılır. örneğin

Test t1;
Test t2 = t1; //copy constructor çalışır.

eğer sınıfınızın üyeleri arasında dinamik bellek ile ayrılmış değişkenler yoksa ( işaretçiler), sizin açıkça bir copy constructor yazmanız çoğu zaman gereksizdir ( gerekli olduğu durumlar da vardır uygulamanıza göre ). Çünkü derleyici otomatik olarak size bir adet constructor ve copy constructor sağlayacaktır. derleyicinin sağladığı copy constructor basitçe değişkenlerin değerlerini kopyalanandan kopyalayana atar. Eğer siz bir copy constructor ve constructor yazarsanız sınıfınıza, derleyici size default olarak bu fonksiyonları artık sağlamaz ve sizin yazdıklarınız geçerli olur. O yüzden eğer bilmeyerek constructor ı private alana koyarsanız, niye nesne oluşturamıyorum diye şaşırmayın:) her zaman nesne oluşturmak istiyorsanız constructorlarınız public alanda olmalı ki dışarıdan çağrılabilsin.

Constructorlarda ki bu çeşitliliğe karşılık destructor her zaman 1 tanedir. Bunun sebebi burada yapılacak işlemelerin genelde kaynakları geri iade etmek ve giriş çıkış işlemlerini tamamlamak gibi giriş parametresine bağlı olmayan değerlerdir. ve nesne yok edilirken kendiliğinden otomatik olarak çağrılmasıdır.

Bu yazımda sizlere convert constructorların bir özelliğinden bahsetmeye ve diğer constructorlar hakkında kısaca bilgi vermeye çalıştım. Bir sonraki yazımda görüşmek üzere...

2 comments:

Anonymous said...

Ya bu ne kardeşim, insan arada bir pasta kek tarifi falan yazar, her gün de kod mod olmaz ki :P

Anonymous said...

This is great info to know.