C++ , Class Yapısına Giriş
|
Inline (yerel) fonksiyonlar
Sınıfın sahip oldugu fonksiyonları, class ile baslayan sınıf tanımı içine yerlestirebiliriz.
Bu tür fonksiyonlara yerel fonksiyonlar (in-line functions ) adı verilmektedir. Yerel fonksiyonlar genel fonksiyonlara oranla daha hızlı çalısır. Bu tür fonksiyonlar programlarının verimini artırırlar.
class test{
fonksiyon(){
fonksiyon içerigi…..
}
};
Örneğin ;
#include <iostream> using namespace std; const float PI = 3.14159; // Bir küre sınıfı... class Kure { public: float r; float x, y, z; // Kürenin hacmini hesaplayan fonksiyon ... inline, yani class içinde tanımı yap//ılmış. float hacim(){ return (r*r*r*4*PI / 3); } // Kürenin alanı..(inline fonksiyon) float alan(){ return (r * r * 4 * PI);} }k; // k bir nesne int main() { k.r=1.0; k.x=2.0; k.y=3.0; k.z=4.0; cout << "X = " << k.x << ", Y = " << k.y << ", Z = " << k.z << ", R = " << k.r << "n" << "Alan =" << k.alan() << "n" << "Hacim=" << k.hacim() << "n"; return 0; }
Gerek duyuldugunda, fonksiyon tanımları sınıfın bildiriminin dısına tasınarak genel fonksiyonlar biçimine dönüstürülebilir. Bu durumda, sınıf tanımı içinde ilgili fonksiyonların prototiplerine yer vermek gerekecektir. Üye fonksiyonların, sınıf dısında tanımlanması durumunda, bu fonksiyonun hangi sınıfın bir üyesi oldugunu da belirtmek gerekmektedir. Bunun için (::) islevinden yararlanılır.
geridönüştipi sınıf_adı :: fonksiyon_adı
Burada geri dönüş tipi bizim fonksiyonun prototipinde belirttiğimiz dönüş tipi olacaktır . Mesela sınıf içinde void kareAl() ; isimli bir fonksiyon prototipi bildirilmiş olsun. Biz sınıf dışında bu fonksiyonun içeriğini yazarken;
void sınıf::kareal(){
…………………………….
}
Örneğin;
#include <iostream> using namespace std; const float PI = 3.14159; // Bir küre sınıfı... class Kure { public: float r; float x, y, z; float alan(); // burada sadece prototip yazıldı.İçeriği sonra tanımlanacak. float hacim(); // bu durumda fonksiyon inline olmayacak ... }k; // Kürenin hacmi.. float Kure::hacim() { return (r*r*r*4*PI / 3); } // Kürenin alanı.. float Kure::alan() { return (r * r * 4 * PI); } int main() { k.r=1.0; k.x=2.0; k.y=3.0; k.z=4.0; cout << "X = " << k.x << ", Y = " << k.y << ", Z = " << k.z << ", R = " << k.r << "n" << "Alan =" << k.alan() << "n" << "Hacim=" << k.hacim() << "n"; return 0; }
Erisimin Sınırlandırılması
Küre ile ilgili sınıfın verilerini (r,x,y,z) ve fonksiyonların özel, yani private olarak tanımlamak istiyoruz. Bunun için bir private anahtar kelimesi kullanmamız yeterli olacaktır ya da public yazmazsak hepsi varsayılan olarak private olacaktır. Erişimi sınırandırdığımız için k nesnesi bu üyelere erişemeyecek ve program hata verecektir.Çünkü private üyelere sadece o sınıfa ait fonksiyonlar erişebilirdi.
Kurucu (Constructors) ve Yok Edici (Destructors) Fonksiyonlar
Program içinde yer alan bir degiskeni asagıda belirtildigibiçimde tanımlayarak, ona belirli bir deger atayabiliriz:
int a; bunu yerine int a=2011;
a = 2011;
Bu sekilde degiskenlere baslangıç degerleri atayabiliyoruz. Bir sınıf içinde yer alan bir degiskene baslangıç degeri atanması söz konusu ise daha farklı bir yol izlenir.
Böyle bir amaca ulasmak için asagıdaki sıra kullanılır;
-> Nesne olusturulur
-> Kurucu (Constructors) Fonksiyon Çagrılır
-> Nesneye ait degiskenlere baslangıç degeri atanır(kurucu fonksiyon ile).
Bir nesne olusturuldugunda, o nesnenin kurucu fonksiyonu otomatik olarak çagrılır.Yani nesne oluşturulduğunda constructor sayesinde değişkenlere başlangıç değerleri atayabiliriz.
Bu nesnenin bildirimi isletildiginde çagrılacagı anlamı tasır. C++’da degisken bildirimleri programın çalıstırılması anında etkin olmaktadır. Bunun nedeni, bir nesne bildiriminin bir kurucu fonksiyonu çagırması ihtimalidir. Nesnenin yok edilmesi esnasında ise yok edici (Destructors) fonksiyon çalıstırılır. Bu fonksiyon nesnenin isgal ettigi alanı bosaltarak bellegin etkin kullanılmasına yardım eder. Yok edici fonksiyonlar da iliskili oldugu sınıf ile aynı isme sahiptir. Ancak fonksiyon adının basına “~” isaret kaydedilir.
fonksiyon_adı();
//kurucu fonksiyon nesne yaratıldıgı anda çagrılarak nesne içindeki degiskenlere ilk deger atar.
~fonksiyon_adı();
//yok edici fonksiyon nesneyi yok ederek nesnenin bellekte isgal ettigi alanı bosaltır.
Kurucu fonksiyon ait oldugu sınıf ile aynı ismi tasır. Bu fonksiyon herhangi bir deger döndürmez. Bunun anlamı, kurucu fonksiyon return sözcügü içermez.
Örneğin ;
#include <iostream> using namespace std; // Sınıf tanımlanıyor.. class testSinif { private: int a,b; public: testSinif(); //constructor , kurucu fonksiyon ~testSinif(); //destructor , yıkıcı fonksiyon void goruntule(); }; // Kurucu fonksiyon.. testSinif::testSinif() { a=10; b=20; } // Yok edici fonksiyon.. testSinif::~testSinif() { } // Degisken degerlerini görüntüler.. void testSinif::goruntule() { cout << a << "n"; cout << b << "n"; } int main() { testSinif ts; //testSinif class'ının ts isimli nesnesi oluşturuldu // ve constructor çağrıldı. ts.goruntule(); return 0; }
Program içinde testSinif isimli bir sınıfımızın var oldugunu varsayalım. Bu sınıf, sınıf adı ile aynı ismi içeren bir kurucu ve bir yok edici fonksiyona sahiptir. Kurucu fonksiyon, a ve b degiskenlerine iki deger atamaktadır. Yok edici fonksiyon ise bu degerleri yok etmektedir.
Parametre Alan Kurucular;
Kurucu fonksiyonlara, diger fonksiyonlarda oldugu gibi parametre geçirmek mümkündür. Bu parametreler genellikle bir nesne olusturuldugunda, onu ilk kullanıma hazırlamak amacıyla kullanabiliriz. Bir kurucuya her zaman sadece bir parametre geçirilmez, birden fazla da parametre geçirilebilir. Birden fazla parametre geçirilmesinde de aynı yol izlenir.
#include <iostream> using namespace std; // Sınıf tanımlanıyor.. class testSinif { int a; public: testSinif(int sayi); ~testSinif(); void goruntule(); }; // Kurucu fonksiyon.. testSinif::testSinif(int sayi) { a=sayi; } // Yok edici fonksiyon.. testSinif::~testSinif() { } // Degisken degerlerini görüntüler.. void testSinif::goruntule() { cout << a << "n"; } int main() { //Kurucuya parametre gönderme islemi testSinif ts(25); //ts nesnesi oluşturulurken parametre olarak 25 değeri verildi // ve constructor a o parametre olarak gönderildi. ts.goruntule(); return 0; }
Bir kurucu fonksiyona bir ya da daha fazla parametre geçirilebiliyordu. Bu parametreler birer sabit olarak ele alınmıstır. Bununla birlikte, gerek duyuldugunda kurucu fonksiyona degiskenler de geçirilebilir.
int main() { cout << “sayi gir:”; cin >> sayi; //Kurucuya gönderilen parametre sabit testSinif ts(25); //Kurucuya gönderilen parametre degisken testSinif ts(sayi); }
Bir Nesneyi Diger Nesneye Atamak
#include <iostream> using namespace std; // Sınıf tanımlanıyor.. class testSinif { int i; public: void ata(int n) { i=n; } int deger() { return i; } }; int main() { testSinif n1, n2; n1.ata(1324); // Bir nesne digerine kopyalanıyor.. n2=n1; cout << "Birinci nesne degeri=" << n1.deger() << "n"; cout << "kinci nesne degeri=" << n2.deger() << "n"; return 0; }
Aynı türdeki bir nesne bir diger nesneye atanabilir. Bunun anlamı, bir nesnenin kopyası olusturulabilir. Nesne bir diger nesneye atandıgında, tüm veri üyelerinin kopyası olusturulur ve kopyalanan nesneye ait veriler aynen kopya nesnelere geçirilir. Program içinde olusturulan n1 ve n2 nesnelerini göz önüne alalım. Bunlardan n1 nesnesine 1324 degerini atadıktan sonra, onu n2 nesnesine kopyalamak istiyoruz.Bunun için yukarıdaki gibi bir yol izlenir ve n1 nesnesi n2 nesnesine kopyalanmış olur.
Fonksiyonlara Nesne Atamak
Diger veri türlerinde oldugu gibi, nesneler de parametreler biçiminde fonksiyonlara aktarılabilir. Fonksiyonun parametresi sınıf tanımı içinde bildirilir. Fonksiyon her çagrıldıgında bu sınıfa ait bir nesne parametre olarak kullanılır. Fonksiyona, diger veri türlerinde oldugu gibi varsayılan olarak nesnelerin degerleri aktarılır.
//parametre olarak //testSinif türünden nesne //alan bir fonksiyon void fonksiyon (testSinif d) { ... ... }
Fonksiyonlara nesne atama yoluyla sayısal degerlerin karesini bulmak istedigimizde; Programda sayi tamsayısını içeren testSinif isimli bir sınıf olusturulmaktadır.Program içinde yer alan kare() fonksiyonunun testSinif türünde bir parametresi vardır. Bu fonksiyon nesneye ait sayi degerinin karesini döndürür. Bu yöntem ile 9 ile 11 sayısal degerlerinin karelerini hesaplayalım;
#include <iostream> using namespace std; // Sınıf tanımlanıyor.. class testSinif { int sayi; public: testSinif(int n){ sayi=n; } int deger(){ return sayi; } }; // Kare alma islemi.. int kare(testSinif d) { return d.deger()*d.deger(); } int main() { // Karesi alınacak degerler.. testSinif a(9), b(11); cout << kare(a) << "n"; cout << kare(b) << "n"; return 0; }
Emeğinize sağlık. Konuyu güzel özetlemişsiniz. Çok faydalı oldu teşekkürler.
Teşekkürler Fatih Bey.
Selamlar,
Çok faideli bir döküman paylaşımı, teşekkür ediyorum.
Saygılarımla,
Arçelik A.Ş E.İ AR-GE SW Developer Eng.
Teşşekür Ederim Murat Bey.