"Enter"a basıp içeriğe geçin

Sınıflar

Sınıflar

Sınıflar nesne tabanlı programlamanın temel yapısıdır. Yapısal programlamadaki structlara  benzerler. Sınıflar gerçek hayatı bilgisayar programlarına uyarlamayı kolaylaştırmak amacıyla kullanılırlar.

Bir sınıf, ona ait nesnelerin temel özelliklerini içinde bulundurur. Mesela insan bizim sınıfımız olsun. Bir insanın boyu, kilosu, yaşı gibi temel özellikleri vardır. Bunlara üye değişken denir.  Bu özelliklerin olması tüm insanlar için ortaktır. Ancak birbirinden farklı insanların bazı özellikleri farklı bazı özellikleri aynı olabilir. İnsan sınıfına ait her kişi bu sınıfın nesnesidir. Bir sınıfa ait sonsuz sayıda nesne oluşturulabilir.

Mesela Ahmet ve Ali adında iki insan olsun. Bunlar insan sınıfının 2 nesnesi olur. Ali’nin boyu 1.70, Ahmet’in boyu 1.80 olabilir. İkisi de 70 kilo da olabilir. Birinin özelliği diğerini etkilemez.

Yani genel olarak sınıflar, içinde kendi üye değişkenleri ve üye fonksiyonları olan,  bu özelliklere ait nesneleri bulunan bir yapılardır. Biz bir nesneye ait fonksiyonu çağırırsak,  bu fonksiyon o nesnenin elemanları üzerinden işlem yapar.

Sınıf oluşturma:  Öncleikle class sınıfismi{}  şeklinde sınıf bloğumuzu oluşturmalıyız. Sınıfımızla ilgili herşey bu iki parantez arasında olmalıdır.  Bir sınıf bloğunda public, privet gibi bölümler vardır. Public kısımdaki değişken ve fonksiyonlara herhangi bir yerden ulaşabiliriz. Privet kısımdaki ögelere ise sadece o nesnenin içerisinden ulaşılabilir. Bir nesnenin ögesine ulaşmak için nesne.oge kullanılır.
Sınıf blokları varsayılan olarak private’tir. public: yazdığımız yerden itibaren public kısmı başlar.
privet: yazarak tekrar privet kısmı başlatabiliriz.

İnsan adında bir class oluşturduk. Private kısımdaki değişkenlere erişmemizi sağlayan fonksiyonlara getter-setter fonksiyonlar denir. Bu sınıfa ait nesnelerin isim değişkenine ve  getter-setter fonksiyonlarına fonksiyonuna kodun herhangi bir  yerinden ulaşabiliriz. Ancak  yaş ve kilo değişkenlerine sadece fonksiyonun içinden ulaşılabilir (kilo değişkeni için setter-getter fonksiyonları tanımlamadım. Kendiniz deneyebilirsiniz.)  Bunun amacı güvenliği sağlamaktır. Böylece private kısımdaki  değişkenleri, erişim sırasında kontrol edebiliriz. Mesela yas değişkenine negatif bir değer girilememesini sağlayabiliriz.  set fonksiyonunu değişkene bizim istediğimiz şartlarda değerler atanabilmesi için düzenleriz. Yani aslında korunması gereken değişkenlere, dolaylı olarak ve kontrolünü sağlayarak ulaşmış oluruz.

Kapsülleme

Sınıflarda bu kontrolü sağlamamızın çeşitli sebepleri olabilir. Örneğin grup halinde yapılan projelerde bizim yazdığımız sınıfın nesnesine başka biri hatalı değer girebilir(yaşa 0 girmek gibi). Bizim yazdığımız sınıfı başkasının değiştirmesini istemeyebiliriz. Yada fonksiyonun içeriğine bakmadan, sadece girdi ve çıktılarıyla ilgilenilebilir.

Bu şekilde, yazdığımız sınıfı private blokla soyutlayarak, sınırlı ve kontrol edilebilir erişim vermeye encapsulation (kapsulleme) denir.

Constructor

Bir nesneyi  oluşturma sırasında içindeki değerleri de belirlememizi sağlayan yapıcı metotlardır. Sınıflar mutlaka constructor içermelidir.

Constructor fonksiyonların isimleri sınıf ile aynıdır. Constructor,  nesne oluştururduğu anda otomatik olarak çalışır. Farklı parametreler ile çalışacak şekilde aşırı yükleyebiliriz. Hangi parametreler ile çalışacağını, nesneyi oluştururken veririz. Hangi imza ile eşleşiyorsa o çalışır. Constructor’lar public alanda tanımlı olmalıdırlar

Hiç parametre almayan yapıcılara default constructor denir. Tüm yeni oluşturulan nesnelere otomatik olarak aynı değerlerin atanmasını sağlar.  Eğer  biz kendimiz bir constructor tanımlamazsak, derleyici bizim için bir default constructor oluşturur ve çöp değerler atar. En az 1 constructor varsa default constructor iptal olur.Tanımlanan constructor’ın default olmaması önemli değildir.

 

Conversion Constructor: Eğer bir sınıfın tek parametre ile çalışan bir constructor’ı varsa, bu constructor o sınıfa otomatik dönüşüme izin verdiği için conversion constructor(dönüşüm yapıcısı) ‘dır.

Örnek vermek gerekirse:

Excplicit: Dönüşüm yapıcısı her zaman istediğimiz bir durum değildir. Mesela  yukarıdaki örnek için düşünürsek:  if(sayi1==19) cout<<”esittir”; dersek , ikisinin eşit olduğunu düşünüp ekrana eşittir basacaktır. Ancak aslında biri integer, diğeri ise bir sınıfa ait bir nesnedir. Bu durum bizim için sıkıntı yaratabilir. excplicit kelimesi conversion constructorun compiler tarafından otomatik olarak çağrılmaması için kullanılır.
Yukarıdaki  örnekte tek parametreli constructor’u   excplicit Sayi(int x) olarak değiştirirsek bu dönüştürme yapılamaz.

Copy constructor: Genel kullanım amacı bir sınıfa ait bir nesne ile aynı özelliklere sahip yeni bir nesne oluşturmaktır. Gerçek bir kopyalama yaptığı (adres ataması yapmadığı) için herhangi  bir veri kaybı olmaz ve birinde yapılan değişiklik diğerini etkilemez

Örnek:   Yukarıdaki örnek için      Insan  insan5(insan3);   dersek insan3 ün özellikleri olan isim=Sadikoglu ve yas=15 değerlerine sahip insan5 adında bir nesne oluşur.

Çoklu tanımlama

Farklı sayıda değişkene sahip imzalarla çalışabilen constructor’lardır

Fonksiyon imzası 

Her fonksiyonun tamamen kendine ait bir imzası vardır. Bir fonksiyon çağrılacağı zaman bu imzaya göre çağrılır. Bir programda aynı imzaya sahip 2 fonksiyon olamaz. Fonksiyon imzası fonksiyonun ismine, kaç parametre aldığına ve parametrelerin türlerine bağlıdır. Dönüş türüne, const olmasına vb bağlı değildir. Fonksiyon prototipi de aslında imzanın tanımlanması içindir.

Header dosyaları

Amaçları okunabilirliği arttırmaktır. Header dosyalarında sınıfın ve içindeki fonksiyonların prototipleri tanımlanır. Tanımlanan fonksiyonlar başka bir c++ dosyası içerisinde gerçeklenir. Böylece sadece header dosyasına bakarak, ayrıntılarla ilgilenmeden sınıfın ne işe yaradığı anlayabiliriz. Karışıklığı engellemiş oluruz.

main.cpp

Standart kütüphaneleri eklemek için #include<> kullanırken Kendi header dosyalarımız için #include”” kullanırız.

Insan.h: Sınıf ve içindeki fonksiyonların prototipleri tanımlanır. Prototipte değişken ismi yazmaya gerek yoktur

Insan.cpp : Tanımlanan fonksiyonlar burada gerçeklenir. Tek dosyada birden çok .h dosyası ve farklı sınıflar gerçeklenebilir.

İlk olarak dönüş tipi belirtilir. Sonra ‘’::’’ kullanarak hangi sınıfa ait bir fonksiyon olduğunu söyleriz.

Binary scope ( :: ) : Binary scope ‘’::’’ kullanarak bir üyenin (değişken, fonksiyon dizi, enum class vb.) hangi sınıfa ait olduğunu gösteririz. Eğer bir sınıf üyesini  o sınıfın dışında kullanacaksak Sınıf::üye şeklinde belirtmemiz gerekir. (nesne.oge şeklindeki erişimler bu kapsama girmez.) Çünkü farklı sınıflarda aynı isme ve imzaya sahip fonksiyonlar bulunabilir ve derleyicinin hangi sınıf için tanımlayacağını bilmesi gerekir
Yani Insan :: setName(const string& name) diyerek, Insan sınıfındaki setname fonksiyonunu gerçekleyeceğimizi söyledik

scope resolution ‘a ihtiyaç duyulan bir diğer yer de, aynı addaki değişkenlerden global olanını kullanmaktır.

Üye ilklendirme söz dizimi (Member initializer list) 

Bir nesnenin üyelerine ilk değer vermek için constructorlar ile birlikte kullanılırlar.

x ve y üyelerine sahip olan, koordinat sisteminde bir noktanın yerini ifade etmek için oluşturulmuş bir Point sınıfımız olsun

Normalde bu sınıf için şu constructor’ı kullanabiliriz:

Ancak bu syntax da aynı işlevi görür:

Yukarıdaki iki kod işlevsel olarak aynıdır. Ancak üye ilklendirme söz dizimi  kullanmak bize performans açısından artış sağlar. Detaylı bilgi için İlklendirme yazıma bakabilirsiniz.

 

    Bu yazı yorumlara kapalı, ama trackback'ler ve pingback'ler açık.