Sunum yükleniyor. Lütfen bekleyiniz

Sunum yükleniyor. Lütfen bekleyiniz

Nesneye Dayalı Programlama

Benzer bir sunumlar


... konulu sunumlar: "Nesneye Dayalı Programlama"— Sunum transkripti:

1 Nesneye Dayalı Programlama
DERS 3 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

2 NESNE MODELLERİ : SINIFLAR
Bu bölümden itibaren C++ programlama dilinin nesneye dayalı programlamaya yönelik özellikleri tanıtılacaktır. Bu özellikler yazılımların kalitesini yükseltmek amacıyla geliştirilmişlerdir. Bilgisayar programı yazmak, aslında gerçek dünyadaki unsurların bilgisayarda birer modellerinin oluşturulması anlamına gelir. Gerçek dünya nesnelerden oluşmaktadır. Bu nedenle bilgisayar programları da bu nesnelerin modellerinden oluşturulmaktadır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

3 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Nesne Nedir? Gerçek dünyada bir nesne iki kısımdan oluşur: 1. Nitelikler. Buna durumlar ya da özellikler de denir. 2. Davranışlar (yetenekler). Nesnelerin bilgisayarda kurulan modellerinde ise aşağıda gösterildiği gibi nitelikleri belirtmek için veriler, davranışları belirtmek için de fonksiyonlar kullanılacaktır. Gerçek dünyada nesne = Nitelikler + Davranışlar Yazılım dünyasında nesne = Veriler + Fonksiyonlar Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

4 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Sınıflar ve Nesneler C++'da nesnelerin modellerini oluşturmak için sınıf ( class) adı verilen bir yapı kullanılmaktadır. Bu yapı bir nesneyi oluşturacak olan verileri ve fonksiyonları birlikte barındırmaktadır. Sınıflar, nesnelerin modeli diğer bir deyişle şablonudur. Programda bir kez sınıf yazılıp şablon oluşturulduktan sonra o sınıftan gerektiği kadar nesne yaratılabilir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

5 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
ÖRNEK 1 Örnek 1: Grafik programlarında kullanılacak nokta nesnelerini tanımlamak üzere bir model. Noktalar iki boyutlu düzlemde yer alacağından özellik olarak iki adet koordinat bilgisine sahiptirler: • x ve y koordinatları. Bu özellikler tamsayı değişkenler ile ifade edilebilirler. Örnek programımızda noktaların sahip olması gereken yetenekler (davranışlar) ise şunlardır: • Noktalar, düzlemde herhangi bir yere konumlanabilmeli: git fonksiyonu • Noktalar bulundukları koordinatları ekrana çıkartabilmeli: goster fonksiyonu • Noktalar, sıfır (0,0) koordinatında olup olmadıkları sorusunu yanıtlayabilmeli: sifir_mi fonksiyonu Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

6 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Nokta sınıfı: class Nokta{ // Nokta Sınıfı int x,y; // Nitelikler: x ve y koordinatları public: void git(int, int); // Noktanın hareket etmesini sağlayan fonksiyon void goster(); // Noktanın koordinatlarını ekrana çıkartır bool sifir_mi(); // Noktanın (0,0) koordinatlarında olup olmadığı }; Bildirim class sözcüğü ile başlar, daha sonra sınıfın ismi gelir (Nokta). Yukarıdaki örnekte önce veriler sonra fonksiyonlar yazılmıştır. Bu sıra ters de olabilir. Sınıfın içindeki veri ve fonksiyonlara o sınıfın üyeleri ( member) denir. Sınıf bildirimi noktalı virgül (;) ile bitirilir. Örnek sınıf bildiriminin içinde fonksiyonların sadece prototipleri yer almaktadır. Fonksiyonların gövdeleri ise ayrı bir yerde tanımlanabilir. Üye fonksiyonlara o sınıfın metotları da ( method) denilmektedir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

7 Üye Fonksiyonların Gövdeleri
// Noktanın hareket etmesini sağlayan fonksiyon void Nokta::git(int yeni_x, int yeni_y) { x = yeni_x; // x koordinatına yeni değer atandı y = yeni_y; // y koordinatına yeni değer atandı } // Noktanın koordinatlarını ekrana çıkaran fonksiyon void Nokta::goster() cout << "X= " << x << ", Y= " << y << endl; // Noktanın (0,0) koordinatlarında olup olmadığını belirten fonksiyon bool Nokta::sifir_mi() return (x == 0) && (y == 0); // x=0 VE y=0 ise doğru Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

8 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Üye fonksiyonların gövdeleri de yazıldıktan sonra Nokta modeli (şablon) tamamlanmıştır. Artık bu sınıftan gerektiği kadar nokta nesnesi yaratılabilir. int main() { Nokta n1,n2; // 2 adet nesne tanımlandı n1 ve n2 n1.git(100,50); // n1 (100,50)'ye gönderiliyor n1.goster(); // n1'in koordinatları ekrana çıkartılıyor n1.git(20,65); // n1 (20,65)'e gönderiliyor if(n1.sifir_mi()) // n1 sıfır da mı? cout << "n1 şu anda sıfır noktasındadır." << endl; else cout << "n1 şu anda sıfır noktasında değildir." << endl; n2.git(0,0); // n2 (0,0)'a gönderiliyor if(n2.sifir_mi()) // n2 sıfır da mı? cout << "n2 şu anda sıfır noktasındadır." << endl; cout << "n2 şu anda sıfır noktasında değildir." << endl; return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

9 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Programda iki adet nesne (n1 ve n2) tanımlanmıştır. Bu nesnelerin üye fonksiyonları çağırılarak nesnelerin belli davranışlarda bulunmaları sağlanmıştır. Nesnelerin metotlarının canlandırılmasına o nesneye mesaj göndermek denir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

10 Kurucu Fonksiyonlar (Constructors)
Kurucu fonksiyonlar üyesi oldukları sınıftan bir nesne yaratılırken kendiliğinden canlanırlar. Bu tür fonksiyonlar bir nesnenin kurulması aşamasında yapılması gereken işleri,örneğin verilere uygun başlangıç değerleri atamak için kullanılırlar. Kurucu fonksiyonlar üyesi oldukları sınıf ile aynı ismi taşırlar. Kurucular parametre alırlar, ancak geri dönüş değerleri yoktur. Geri dönüş tipi olarak herhangi bir tip (void bile) yazılmaz. Kurucu fonksiyonlar nesne yaratılırken sınıfın dışından sınıfın açık (public) üyeleri arasında yer almalıdırlar. Kurucu fonksiyonlar işlevlerine ve yapılarına göre bazı alt gruplara ayrılırlar. İlk grupta parametre verilmeden çağrılabilen parametresiz kurucu fonksiyonlar yer alır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

11 Parametresiz Kurucu Fonksiyonlar ( Default Constructor)
Bu tür kurucu fonksiyonların ya parametre listeleri boştur, ya da tüm parametrelerin bir başlangıç değeri vardır. class Nokta{ // Nokta Sınıfı int x,y; // Nitelikler: x ve y koordinatları public: Nokta(); // Kurucu fonksiyon bildirimi bool git(int, int); // Noktanın hareket etmesini sağlayan fonksiyon void goster(); // Noktanın koordinatlarını ekrana çıkartır }; // Parametresiz Kurucu Fonksiyon Nokta::Nokta() { cout << "Kurucu fonksiyon çalışıyor..." << endl; x = 0; // Koordinatlar sıfırlanıyor. y = 0; } Ana programda kurucu fonksiyonların çağrılması için özel bir deyim yazılmaz. Nesnelerin yaratıldığı satırlarda kurucu fonksiyon her nesne için bir defa çalışır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

12 Parametreli Kurucu Fonksiyonlar
Kurucu fonksiyonlar da diğer üye fonksiyonlar gibi gerektiğinde parametre alacak şekilde tanımlanabilirler Bu durumda sınıftan nesne yaratan programcılar, nesneleri tanımladıkları satırlarda kurucu fonksiyonlara uygun tipte ve sayıda argümanı vermek zorundadırlar. class Nokta{ // Nokta Sınıfı int x,y; // Nitelikler: x ve y koordinatları public: Nokta(int,int); // Kurucu fonksiyon bildirimi bool git(int, int); // Noktanın hareket etmesini sağlayan fonksiyon void goster(); // Noktanın koordinatlarını ekrana çıkartır }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

13 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// Parametreli Kurucu Fonksiyon Nokta::Nokta(int ilk_x, int ilk_y) { cout << "Kurucu fonksiyon çalışıyor..." << endl; if ( ilk_x < 0 ) // Verilen değer negatifse x = 0; // Koordinat sıfırlanıyor else x = ilk_x; if ( ilk_y < 0 ) // Verilen değer negatifse y = 0; // Koordinat sıfırlanıyor y = ilk_y; } // Ana Program int main() Nokta n1(20,100), n2(-10,45); // Kurucu 2 kez çalışır Nokta *pn = new Nokta(10,50); // Kurucu 1 kez çalışır. // Nokta n3; // HATA! Parametresiz kurucu yok n1.goster(); / n1'in koordinatları ekrana çıkartılıyor n2.goster(); //n2'nin koordinatları ekrana çıkartılıyor pn->goster(); //pn2'nin işaret ettiği nesne ekrana çıkar return 0; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

14 Kurucu Parametrelerine Başlangıç Değeri Verilmesi:
Diğer fonksiyonlarda olduğu gibi kurucu fonksiyonların parametrelerine de başlangıç değeri verilebilir. Bu durumda nesne yaratılırken verilmeyen argümanların yerine parametrelerin başlangıç değerleri kullanılacaktır. // Kurucu Fonksiyon Nokta::Nokta(int ilk_x = 0, int ilk_y = 0) { cout << "Kurucu fonksiyon çalışıyor..." << endl; if ( ilk_x < 0 ) // Verilen değer negatifse x = 0; // Koordinat sıfırlanıyor else x = ilk_x; if ( ilk_y < 0 ) // Verilen değer negatifse y = 0; // Koordinat sıfırlanıyor y = ilk_y; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

15 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Bu sınıftan aşağıdaki gibi nesneler yaratılabilir. Nokta n1(15,75); // x=15, y=75 Nokta n2(100); // x=100, y=0 Bu fonksiyon parametresiz bir kurucu olarak da kullanılabilir. Nokta n3; // x=0, y=0 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

16 Bir Sınıfta Birden Fazla Kurucu Fonksiyon Olması:
Bir sınıfta birden fazla kurucu fonksiyon bulunabilir. Fonksiyon isimlerinin yüklenmesi ( function overloading) konusunda da değinildiği gibi isimleri aynı olan bu fonksiyonların bir belirsizlik olmadan çağrılabilmeleri için parametrelerinin tipleri ve/veya sayıları farklı olmalıdır. Nokta::Nokta() // Parametresiz kurucu fonksiyon { // Gövdesi önemli değil } Nokta::Nokta(int ilk_x, int ilk_y) // Parametreli kurucu fonksiyon // Gövdesi önemli değil Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

17 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
İki kurucuya sahip bir Nokta sınıfından farklı şekillerde nesneler yaratılabilir. Nokta n1; // Parametresiz kurucu çalışır Nokta n2(30,10); // Parametreli kurucu çalışır Örnek sınıfta tek parametreli bir kurucu olmadığından aşağıdaki satır hatalıdır. Nokta n3(10); // HATA! Bir parametreli kurucu yok Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

18 Kurucuların Nesne Dizileri ile Kullanılması
Bir sınıfta parametresiz bir kurucu fonksiyon varsa bu sınıftan bir nesne dizisi yaratıldığında dizinin her elemanı için kurucu fonksiyon kendiliğinden canlanır. Nokta dizi[10]; // Parametresiz kurucu 10 defa çalışır Eğer bir parametre alan kurucu fonksiyona sahip bir sınıftan nesne dizisi yaratılacaksa, kurucuya gerekli argümanları göndermek için başlangıç değerleri listesi kullanılır. Bu listenin başı ve sonu kıvırcık parantezler ({ }) ile belirlenir.Ayrıca kurucuya gönderilecek her değer de kıvırcık parantezler içine yazılır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

19 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// Kurucu Fonksiyon Nokta::Nokta(int ilk_x, int ilk_y = 0) Nokta dizi[]= { {10} , {20} , Nokta(30,40) }; // 3 elemanlı nesne dizisi Eğer Nokta sınıfında yukarıdaki kurucu fonksiyona ek olarak parametresiz bir kurucu fonksiyon da yer alsaydı aşağıda gösterildiği gibi 5 elemanlı bir dizi yaratılabilirdi. Nokta dizi[5]= { {10} , {20} , Nokta(30,40) }; // 5 elemanlı nesne dizisi Yukarıda başlangıç değerleri listesine sadece üç değer vardır. Bu durumda dizinin ilk üç elemanına listedeki değerler sırasıyla gönderilecektir. Son iki eleman için ise parametresiz kurucu fonksiyon çalıştırılacaktır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

20 Kurucu Fonksiyonlarda İlk Değer Atama ( Constructor Initializers)
Kurucu fonksiyonlarda nesnelerin verilerine ilk değerlerini atamak için C++'nın atama deyiminden daha farklı bir yapı da kullanılabilmektedir. Özellikle sabit verilere ilk değerlerini atamak için bu yapının kullanılması zorunludur. Bir sınıfın kurucu fonksiyonunda sabit veriye başlangıç değeri atanmaya çalışılırsa derleme hatası oluşur, çünkü sabit bir veri bir atama işleminin solunda yer alamaz. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

21 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
class C{ // Örnek C sınıfı const int ci; // sabit üye veri int x; // sabit olmayan üye veri public: C() { // Kurucu fonksiyon x = -2; // Doğru, çünkü x sabit değil ci = 0; // HATA! Çünkü ci sabit } }; Aşağıdaki gibi bir yazım da derleme hatasına neden olur. const int ci = 10; // HATA! sabit üye veri Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

22 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Bu problemin kurucu fonksiyonlarda ilk değer atama yapısı ( constructor initializer) kullanılarak çözülür. Kurucularda verilere ilk değer atamak için kurucu fonksiyonun imzasından sonra iki nokta üst üste (:) konur, ardından ilk değer atanacak verinin adı gelir ve parantez içinde atanacak değer yazılır. class C{ // Örnek C sınıfı const int ci; // sabit üye veri int x; // sabit olmayan üye veri public: C():ci(0) { // Kurucu fonksiyon. ci'ye sıfır atanıyor. x = -2; // Doğru, çünkü x sabit değil } }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

23 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Tüm üye verilere değer atamak için bu yapı kullanılabilir. Eğer kurucu fonksiyonun değer atamaktan başka bir görevi yoksa gövdesi boş kalabilir. class C{ // Örnek C sınıfı const int ci; // sabit üye veri int x; // sabit olmayan üye veri public: C():ci(0), x(-2) // Kurucu fonksiyon, ilk değerler atanıyor { } // Gövde boş }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

24 Yok Edici Fonksiyonlar ( Destructors)
Bu fonksiyonlar üyesi oldukları sınıftan yaratılmış olan bir nesne bellekten kaldırılırken kendiliğinden çalışırlar. Bir nesnenin bellekten kaldırılması için ya nesnenin yaşam alanı sona ermelidir (tanımlandığı blok sona ermiştir) ya da dinamik bellekte tanımlanmış olan bir nesne delete operatörü ile bellekten silinmelidir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

25 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Yok edici fonksiyonlar da kurucular gibi sınıf ile aynı ismi taşırlar, ancak isimlerinin önünde 'tilda' simgesi (~) yer alır. Yok ediciler parametre almazlar ve geriye değer döndürmezler. Bir sınıfta sadece bir adet yok edici fonksiyon olabilir. class String{ // Örnek (karakter katarı) String sınıfı int boy; // Katarın boyu char *icerik; // Katarın içeriği public: String(const char *); // Kurucu void goster(); // Katarları ekrana çıkaran üye fonksiyon ~String(); // Yok edici fonksiyon }; C++ standart arşivinde katarları tanımlamak için string adında hazır bir sınıf vardır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

26 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// Kurucu Fonksiyon String::String(const char *gelen_veri) { cout<< "Kurucu çalıştı" << endl; boy = strlen(gelen_veri); // gelen dizinin boyu hesaplandı icerik = new char[boy +1]; // icerik için yer ayrıldı. +1 null için strcpy(icerik, gelen_veri); // gelen veri icerik'in gösterdiği yere } void String::goster() cout<< icerik << ", " << boy << endl; // Katar içeriği ve boyu ekrana // Yok edici Fonksiyon String::~String() cout<< "Yok edici çalıştı" << endl; delete[] icerik; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

27 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// Ana Program int main() { String string1("Katar 1"); String string2("Katar 2"); string1.goster(); string2.goster(); return 0; // Yok edici iki defa çalışır } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

28 Kopyalama Kurucusu (Copy Constructor)
Kopyalama kurucusu özel bir kurucu fonksiyondur. Diğer kurucu fonksiyonlar gibi bir nesne yaratılırken kendiliğinden canlanırlar. Var olan bir nesnedeki verileri yeni yaratılan nesnenin içine kopyalarlar. Böylece yeni yaratılan nesne var olan eski bir nesnenin kopyası olur. Bu fonksiyonlar giriş parametresi olarak aynı sınıftan bir nesneye referans alırlar. Bu kopyası çıkarılacak olan nesneye bir referanstır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

29 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Eğer programcılar sınıflarının içine bir kopyalama kurucusu koymazlarsa, derleyici standart bir kurucuyu sınıfa yerleştiriri. Standart kopyalama kurucusu bir nesnenin elemanlarını bire bir yeni nesnenin veri alanlarına kopalar. İçinde işaretçi olmayan nesneler için bu genellikle yeterlidir. Örneğin bir önceki örnekteki String sınıfı için derleyicinin yerleştireceği kopyalamakurucusu aşağıdaki işlemleri yapacaktır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

30 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
String sınıfı için verilen örnekte de görüldüğü gibi derleyicinin sağladığı kopyalama fonksiyonu sadece nesnenin elemanlarını kopyalamaktadır. İşaretçilerin işaret ettiği veriler kopyalanamaz. Bu alanların da kopyalanması isteniyorsa programcı kendi kopyalama fonksiyonunu yazmalıdır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

31 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
class String{ // Örnek (karakter katarı) String sınıfı int boy; // Katarın boyu char *icerik; // Katarın içeriği public: String(const char *); // Kurucu String(const String &); // Kopyalama kurucusu void goster(); // Katarları ekrana çıkaran üye fonksiyon ~String(); // Yok edici fonksiyon }; String::String(const String &gelen_nesne) // Kopyalama kurucusu { boy = gelen_nesne.boy; icerik = new char[boy + 1]; // +1 null karakteri icin strcpy(icerik, gelen_nesne.icerik); } int main() // Ana fonksiyon String string1("Katar 1"); string1.goster(); String diger = string1; // Kopyalanma kurucusu çalışır String baska(string1); // Kopyalanma kurucusu çalışır diger.goster(); baska.goster(); return 0; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

32 Sabit Nesneler ve Sabit Fonksiyonlar
Diğer veri tiplerinde olduğu gibi bir nesne de sabit (const) olarak tanımlanabilir. Bunun anlamı nesnenin veri alanlarının program boyunca doğrudan ya da dolaylı olarak (fonksiyon çağırarak) değiştirilemeyeceğidir. const Nokta sn(10,20); // Sabit nokta Derleyiciler sabit olarak tanımlanan nesnelerin içeriklerinin değişmemesi için bu nesnelerin üye fonksiyonlarının çağırılmasına izin vermezler. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

33 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Sınıfın yazarları üye veriler üzerinde değişiklik yapmayan fonksiyonları da sabit (const) olarak bildirmelidirler. Sabit nesneler için sadece sabit fonksiyonlar çağırılabilirler. class Nokta{ // Nokta Sınıfı int x,y; // Nitelikler: x ve y koordinatları public: Nokta(); // Kurucu fonksiyon bildirimi bool git(int, int); // Noktanın hareket etmesini sağlayan fonksiyon void goster() const; // sabit fonksiyon, koordinatları ekrana çıkartır }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

34 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
void Nokta::goster() const { cout << "X= " << x << ", Y= " << y << endl; } int main() const Nokta sn(10,20); // sabit nokta Nokta n(0,50); // sabit olmayan nokta sn.goster(); // Doğru sn.git(30,15); // HATA! n.git(100,45); // Doğru return 0; Sınıfın verileri üzerinde değişiklik yapmayan fonksiyonların sabit olarak tanımlanmaları hata olasılığını ve hata çıktığında incelenmesi gereken fonksiyonların sayısını azaltmaktadır. Bu nedenle bu özelliğe uyan tüm üye fonksiyonlar sabit olarak tanımlanmalıdır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

35 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Statik Üyeler Bir sınıftan tanımlanan her nesne için bellekte farklı veri alanları yaratılır. Ancak bazı durumlarda tüm nesnelerin ortak bir veriyi (bellek gözünü) paylaşmaları gerekli olabilir. Bellekte sadece tek kopyasının yaratılması istenen üye veriler static olarak tanımlanmalıdırlar. class A{ char c; static int i; }; int main() { A p,q,r; : } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

36 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Statik üyeler nesne tanımlanmadan önce bellekte yaratılırlar. Statik üyeler de diğerleri gibi özel (private) veya açık (public) olabilirler. Açık statik üyeler, global veriler gibi programın tüm alanlarından erişilebilirler. Bunun için sınıfın ismi ve ‘scop’ operatörü (::) kullanılır. A::i= 5; Statik üyeler özel (private) olarak tanımlanırsa bu üyelere doğrudan erişmek mümkün olmaz. Henüz nesne yaratılmadan önce bu verilere başlangıç değeri atamak için statik fonksiyonlar tanımlanır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

37 Nesnelerin Fonksiyonlara Parametre Olarak Aktarılması
Aksi zorunlu olmadıkça, nesneler fonksiyonlara referanslar yoluyla aktarılmalı. Benzer şekilde fonksiyonlardan geri döndürülen nesneler için de eğer mümkünse referanslar kullanılmalıdır. Parametre aktarımında referanslar kullanılmazsa nesnelerin içerdiği değerler yığına kopyalanır ( call by value). Eğer sınıfın içinde bir kopyalama fonksiyonu varsa yığına kopyalama işi için de programcının yazdığı bu fonksiyon canlanacaktır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

38 Örnek 2: Nesnelerin fonksiyonlara değer olarak aktarılması
// o47.cpp // Nesnelerin fonksiyonlara değer olarak aktarılması // Uygun Yöntem DEĞİLDİR! #include <iostream> using namespace std; // Karmaşık (Kompleks) sayıları tanımlamak için oluşturulan sınıf class ComplexT{ float re,im; // reel ve sanala kısımlar static unsigned int sayac; // Bu sınıftan yaratılan nesne sayisinı tutar public: ComplexT(float re_in=0,float im_in=1); // Kurucu ComplexT(const ComplexT &); // Kopyalama kurucusu ComplexT topla(ComplexT) const; // Parametre olarak nesne alan metot void goster() const; // Bilgileri ekrana çıkarır static void sifirla(){sayac=0;} // Sayacı sıfırlayan static metot ~ComplexT(); // Yok edici }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

39 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
//Parametrsiz çağırılabilen kurucu // İlk değerleri atar. Yaratılan nesne sayisinı arttırır. ComplexT::ComplexT(float re_in,float im_in) { re=re_in; im=im_in; sayac++; // Nesne sayisi arttırıldı cout<< endl << "Kurucu calisti. "; cout<< "Nesne sayisi = "<< sayac; } // Kopyalama Kurucusu // Nesnenin verilerini kopylar // Yaratılan nesne sayisinı arttırır ComplexT::ComplexT(const ComplexT &c) re=c.re; // Elemanlar kopyalanıyor im=c.im; sayac++; // Nesne sayisi arttırıldı cout<< endl << "Kopyalama kurucusu calisti. "; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

40 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// İki karmaşık sayıyı toplayıp üçüncü bir sayı elde eden metot // Giriş parametresi değer olarak (call by value) alınan bir nesnedir. // Parametrenin bu şekilde alınması uygun DEĞİLDİR! ComplexT ComplexT::topla(ComplexT c) const { cout<< endl << "Toplama metodu calisiyor"; ComplexT sonuc; // Sonucun yazılacağı 3. nesne sonuc.re=re+c.re; // Alt alanlar toplanıyor sonuc.im=im+c.im; return sonuc; // sonuc nesnesi geri döndürülüyor. } // Nesne ile ilgili bilgileri ekrana çıkaran metot void ComplexT::goster() const cout << endl << "re= " << re << " , im= " << im; cout << " Nesne sayisi= " << sayac; // Yok edici fonksiyon // Yaratrılan nesne sayisinı bir azaltır ComplexT::~ComplexT() sayac--; // Nesne sayisi azaltıldı cout<< endl << "Yok edici calisti. "; cout<< "Nesne sayisi = "<< sayac; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

41 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
unsigned int ComplexT::sayac; // static sayac icin bellekte yer ayrıldı // Ana program int main() { ComplexT::sifirla(); // sayac sıfırlandı ComplexT z1,z2,z3; // Üç adet nesne yarıtıldı z3=z1.topla(z2); // z3 = z1 + z2 işlemi yapılıyor. z3.goster(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

42 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Nesnelerin fonksiyonlara değer olarak aktarılması hem bellekte daha fazla yer harcanmasına neden olur hem de programın çalışmasını yavaşlatır. Bu nedenle, eğer aksi zorunlu değilse, fonksiyonlara nesnelerin değerleri değil referansları aktarılmalıdır. Referans yoluyla aktarılan nesnelerin içeriklerinin fonksiyon içinde değiştirilmesi istenmiyorsa bu aktarım sabit referanslar ile yapılmalıdır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

43 Örnek 3: Nesnelerin fonksiyonlara referans olarak aktarılması
// o48.cpp // Nesnelerin fonksiyonlara referans olarak aktarılması #include <iostream> using namespace std; // Karmaşık (Kompleks) sayıları tanımlamak için oluşturulan sınıf class ComplexT{ float re,im; // reel ve sanala kısımlar static unsigned int sayac; // Bu sınıftan yaratılan nesne sayisinı tutar public: ComplexT(float re_in=0,float im_in=1); // Kurucu ComplexT(const ComplexT &); // Kopyalama kurucusu ComplexT topla(const ComplexT &) const; // Parametre olarak nesneye referans alan metot void goster() const; // Bilgileri ekrana çıkarır static void sifirla(){sayac=0;} // Sayacı sıfırlayan static metot ~ComplexT(); // Yok edici }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

44 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
//Parametrsiz çağırılabilen kurucu // İlk değerleri atar. Yaratılan nesne sayisinı arttırır. ComplexT::ComplexT(float re_in,float im_in) { re=re_in; im=im_in; sayac++; // Nesne sayisi arttırıldı cout<< endl << "Kurucu calisti. "; cout<< "Nesne sayisi = "<< sayac; } // Kopyalama Kurucusu // Nesnenin verilerini kopylar // Yaratılan nesne sayisinı arttırır ComplexT::ComplexT(const ComplexT &c) re=c.re; // Elemanlar kopyalanıyor im=c.im; sayac++; // Nesne sayisi arttırıldı cout<< endl << "Kopyalama kurucusu calisti. "; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

45 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// İki karmaşık sayıyı toplayıp üçüncü bir sayı elde eden metot // Giriş parametresi referans olarak (call by address) alınan bir nesnedir. ComplexT ComplexT::topla(const ComplexT & c) const { cout<< endl << "Toplama metodu calisiyor"; ComplexT sonuc; // Sonucun yazılacağı 3. nesne sonuc.re=re+c.re; // Alt alanlar toplanıyor sonuc.im=im+c.im; return sonuc; // sonuc nesnesi geri döndürülüyor. } // Nesne ile ilgili bilgileri ekrana çıkaran metot void ComplexT::goster() const cout << endl << "re= " << re << " , im= " << im; cout << " Nesne sayisi= " << sayac; // Yok edici fonksiyon // Yaratrılan nesne sayisinı bir azaltır ComplexT::~ComplexT() sayac--; // Nesne sayisi azaltıldı cout<< endl << "Yok edici calisti. "; cout<< "Nesne sayisi = "<< sayac; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

46 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
unsigned int ComplexT::sayac; // static sayac icin bellekte yer ayrıldı // Ana program int main() { ComplexT::sifirla(); // sayac sıfırlandı ComplexT z1,z2,z3; // Üç adet nesne yarıtıldı z3=z1.topla(z2); // z3 = z1 + z2 işlemi yapılıyor. z3.goster(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

47 Fonksiyonlardaki Geçici Nesnelerin Azaltılması
Örnek 4’de toplama fonksiyonunda iki nesneyi toplamak için geçici bir nesne yaratılmaktadır. Bu işlem kurucu ve yok edici fonksiyonların çalışmasına neden olmaktadır. Ardından bu geçici nesne fonksiyondan geri gönderileceği için (return gecici;) yığına kopyalanmaktadır. Bu işlemleri azaltmak için geçici bir nesne yaratmak yerine, işlemler geçici değişkenler üzerinde yapılır. Daha sonra fonksiyondan değer döndürülürken nesne yaratılır. ComplexT ComplexT::topla(const ComplexT & z) const { float gecici_re, gecici_im; // Bütün bir nesne yerine sadece geçici değişkenler gecici_re = re + z.re; // Toplama işlemi yapılıyor gecici_im = im + z.im; return ComplexT(gecici_re,gecici_im); // Nesne yaratılıyor, kurucu canlanır } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

48 Örnek 4:Fonksiyonlardaki yerel nesnelerin azaltılması
#include <iostream> using namespace std; // Karmaşık (Kompleks) sayıları tanımlamak için oluşturulan sınıf class ComplexT{ float re,im; // reel ve sanal kısımlar static unsigned int sayac; // Bu sınıftan yaratılan nesne sayisinı tutar public: ComplexT(float re_in=0,float im_in=1); // Kurucu ComplexT(const ComplexT &); // Kopyalama kurucusu ComplexT topla(const ComplexT &) const; // Parametre olarak nesneye referans alan metot void goster() const; // Bilgileri ekrana çıkarır static void sifirla(){sayac=0;} // Sayacı sıfırlayan static metot ~ComplexT(); // Yok edici }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

49 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
//Parametrsiz çağırılabilen kurucu // İlk değerleri atar. Yaratılan nesne sayisinı arttırır. ComplexT::ComplexT(float re_in,float im_in) { re=re_in; im=im_in; sayac++; // Nesne sayisi arttırıldı cout<< endl << "Kurucu calisti. "; cout<< "Nesne sayisi = "<< sayac; } // Kopyalama Kurucusu // Nesnenin verilerini kopylar // Yaratılan nesne sayisinı arttırır ComplexT::ComplexT(const ComplexT &c) re=c.re; // Elemanlar kopyalanıyor im=c.im; sayac++; // Nesne sayisi arttırıldı cout<< endl << "Kopyalama kurucusu calisti. "; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

50 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// İki karmaşık sayıyı toplayıp üçüncü bir sayı elde eden metot // Giriş parametresi referans olarak (call by address) alınan bir nesnedir. ComplexT ComplexT::topla(const ComplexT & z) const { cout<< endl << "Toplama metodu calisiyor. "; float gecici_re, gecici_im; // Bütün bir nesne yerine sadece geçici değişkenler gecici_re = re + z.re; // Toplama işlemi yapılıyor gecici_im = im + z.im; return ComplexT(gecici_re,gecici_im); // Nesne yartılıyor, kurucu canlanır } // Nesne ile ilgili bilgileri ekrana çıkaran metot void ComplexT::goster() const cout << endl << "re= " << re << " , im= " << im; cout << " Nesne sayisi= " << sayac; // Yok edici fonksiyon // Yaratrılan nesne sayisinı bir azaltır ComplexT::~ComplexT() sayac--; // Nesne sayisi azaltıldı cout<< endl << "Yok edici calisti. "; cout<< "Nesne sayisi = "<< sayac; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

51 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
unsigned int ComplexT::sayac; // static sayac icin bellekte yer ayrıldı // Ana program int main() { ComplexT::sifirla(); // sayac sıfırlandı ComplexT z1,z2,z3; // Üç adet nesne yarıtıldı z3=z1.topla(z2); // z3 = z1 + z2 işlemi yapılıyor. z3.goster(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

52 İç içe nesneler: Nesnelerin başka sınıfların üyesi olması
Bir sınıfın üyeleri sadece hazır veri tipleri (char, int, double....) olmak zorunda değildir. Bir sınıfın üyeleri başka sınıftan tanımlanmış nesneler de olabilirler. Sınıflar arası bu ilişkiye sahip olma ilişkisi (has a relation) adı verilir. Şekildeki örnekte karmaşık sayıları tanımlamak üzere bir sınıf (ComplexKes) oluşturulmuştur. Bu sınıfın reel ve sanal kısımları bayağı kesirlerden oluşacaklardır. Bayağı kesirler ise (Kesir) sınıfından tanımlanan nesneler ile oluşturulacaktır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

53 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Burada ComplexKes sınıfının kurucusunu yazan programcı, kullandığı nesnelerin (Kesir sınıfından re ve im) kurucularına uygun parametreleri göndermekle yükümlüdür. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

54 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Örnek olarak hazırlanan Kesir sınıfı: class Kesir{ // Bayağı kesirleri tanımlamak için int pay,payda; public: Kesir(int, int); // Kurucu void goster() const; }; Kesir::Kesir(int py, int pyd) // KURUCU { pay=py; if (pyd==0) payda=1; // Payda olarak 0 verilirse payada=1 olur else payda=pyd; cout << "Kesir'in kurucusu" << endl; } // Bayağı kesiri ekrana çıkaran fonksiyon void Kesir ::goster() const cout << pay << "/" << payda << endl; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

55 Örnek olarak hazırlanan ComplexKes sınıfı:
// Elemanları bayağı kesir olan karmaşık sayıları tanımlayan sınıf class ComplexKes{ Kesir re,im; // üye nesneler public: ComplexKes(int,int); // Kurucu void goster() const; }; // Kurucu fonksiyon // Önce üye nesnelerin kurucularına gerekli parametreler gönderiliyor ComplexKes::ComplexKes(int re_in,int im_in) : re(re_in,1), im(im_in,1) { .... } // Karmaşık sayı ekrana çıkarılıyor void ComplexKes::goster() const re.goster(); im.goster(); Üye nesnelerin kurucuları canlanır int main() // Ana program { ComplexKes ck(2,5); // Bir karmaşık sayı tanımlanıyor ck.goster(); // Karmaşık sayı ekrana çıkarılıyor return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

56 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Değerlendirme: Sınıflar ve nesneler hakkında bu aşamaya kadar öğrendiklerimizi değerlendirdiğimizde şu sonuçlara varabiliriz: Sınıflar 'aktif' veri tipleridir. Bu tiplerden nesneler tanımlanır. Nesnelere mesajlar gönderildiğinde nesneler bir davranışta bulunarak cevap verirler. Sınıflar hem verileri hem de bu veriler üstünde işlem yapan fonksiyonları aynı paket içinde barındırırlar ( encapsulation). Bunun sonucu olarak: Nesneler gerçek dünyadakine benzer şekilde modellenebilir, Program daha kolay okunabilir, çünkü birbirleriyle ilgili olan veriler ve fonksiyonlar bir aradadır, Hataları bulmak kolay olur, çünkü bu veriler üzerinde işlem yapabilen fonksiyonlar bellidir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

57 Metotların inline Fonksiyon (Makro) Olarak Tanımlanmaları:
Örnek 1'deki Nokta sınıfının bildiriminde metotların (üye fonksiyonların) sadece prototipleri yer almaktadır. Fonksiyonların gövdeleri ise sınıfın dışında tanımlanmıştı. Metotların gövdeleri de sınıf bildiriminin içine yazılabilir. Bu durumda o fonksiyon makro (inline) olarak tanımlanmış olur. Aşağıdaki örnekte sifir_mi adlı üye fonksiyon sınıfın içine yazılarak makro olarak tanımlanmıştır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

58 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
class Nokta{ // Nokta Sınıfı int x,y; // Nitelikler: x ve y koordinatları public: void git(int, int); // Noktanın hareket etmesini sağlayan fonksiyon void goster(); // Noktanın koordinatlarını ekrana çıkartır bool sifir_mi() // Noktanın (0,0) koordinatlarında olup olmadığı (makro) { return (x == 0) && (y == 0); } }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

59 Nesnelerin Dinamik Olarak Yaratılması:
Derleyicinin hazır veri tipleri (int, float, char vs.) veri tanımlamak için nasıl kullanılıyorsa sınıflar da nesne tanımlamak için aynı şekilde kullanılabilir. Örneğin nesnelere işaret edebilen işaretçiler tanımlanabilir ve bu işaretçiler için dinamik bellekten yer alınabilir ve daha önce alınmış olan yerler geri verilebilir. Aşağıdaki programda nesnelere işaret edebilen iki işaretçi (pn1 ve pn2) tanımlanmakta, dinamik bellekte bu işaretçiler tarafından işaret edilen nesneler yaratılmaktadır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

60 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
int main() { Nokta*pn1 = new Nokta; //pn1'in gösterdiği nesne için bellekten yer alındı Nokta*pn2 = new Nokta; //pn2'nin gösterdiği nesne için bellekten yer alındı pn1->git(50,50); //pn1'in gösterdiği nesneye git mesajı pn1->goster(); //pn1'in gösterdiği nesneye goster mesajı pn2->git(100,150); //pn2'nin gösterdiği nesneye git mesajı if(pn2->sifir_mi()) // pn2'nin gösterdiği nesne sıfır da mı? cout << "pn2'nin nesnesi şu anda sıfır noktasındadır." << endl; else cout << "pn2'nin nesnesi şu anda sıfır noktasında değildir." << endl; delete pn1; // Dinamik bellekten alınan yerler geri veriliyor delete pn2; return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

61 Nesnelerin Dizi Olarak Yaratılması:
Sınıflardan, nesne dizileri de tanımlamak mümkündür. Aşağıdaki örnekte Nokta sınıfından, adı dizi olan 10 elemanlı bir nesne dizisi yaratılmış ve kullanılmıştır. int main() { Nokta dizi[10]; // 10 elemanlı dizi yaratılıyor. dizi[0].git(15,40); // dizinin ilk elemanına (0 indisli) git mesajı dizi[1].git(75,35); //dizinin ikinci elemanına (1 indisli) git mesajı : // Diğer elemanlar da konumlandırılır for (int i= 0; i < 10; i++) // dizideki tüm nesneler ekrana çıkartılıyor dizi[i].goster(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

62 Sınıf Üyelerine Erişimin Denetlenmesi
Programcılar, sınıfların oluşturulması ve kullanılması açısından ikiye ayrılırlar. Birincisi sınıfları yazan programcılardır. İkincisi ise sınıfları kullanarak nesneler yaratan ve bu nesnelere mesajlar göndererek onların canlandıran programcılardır. Sınıfı oluşturan programcı sınıf yapısının doğru çalışmasından sorumludur. Sınıfı nesne tanımlamak için kullanan programcı sınıfın iç yapısını bilmek zorunda değildir. Bilmesi gereken tek şey nesnelere nasıl mesaj yollanacağıdır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

63 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Bu özellikleri sağlamak için, sınıfı yazan programcı, sınıfın bazı üyelerini gizleyerek ( data hiding) onlara sınıf dışından erişilmesini engelleyebilir. Bir sınıfın içindeki üyelere erişimi denetleyen üç farklı etiket bulunmaktadır: public (açık), private (özel) ve protected (korumalı). Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

64 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Açık (public) olarak tanımlanan üyelere, bu sınıftan yaratılan tüm nesneler yoluyla erişilebilir. Özel (private) olarak tanımlanan üyelere (veri ve fonksiyon) ise sadece sınıfın içindeki fonksiyonlar erişebilir. Bu sınıftan yaratılan nesneler üzerinden özel üyelere erişmek mümkün değildir. Korumalı (protected) üyeler ise kalıtım ( inheritance) özelliği ile birlikte kullanılmaktadır. Kalıtım konusu anlatılırken korumalı erişim yöntemi de açıklanacaktır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

65 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Bir sınıfın içindeki açık elemanlar o sınıfın dışarıya verdiği hizmetleri ( services) tanımlarlar. Bunların tümüne sınıfın arayüzü ( interface) denir. Özel üyeler sınıfın gerçeklenmesiyle ( implementation) ilgili olduklarından sınıfın kullanıcılarını ilgilendirmezler. Bir sınıftaki üyelerin erişim tipi normalde özeldir (private). Sınıfın yazarı dışarıya açmak istediği üyelerin tanımından önce public: etiketini koyar. Bu nedenle örnekteki Nokta sınıfındaki ilk iki üye (x , y) özeldir ve dışarıya kapalıdır. Ana programda yaratılan nesneler üzerinden bu verilere erişmek mümkün değildir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

66 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

67 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Örnek olarak Nokta sınıfından üretilen noktaların hareket alanlarının x ekseninde 0-500, y ekseninde ise aralığında olması ve noktalar bu alanın dışına çıkamamaları istensin. class Nokta{ // Nokta Sınıfı int x,y; // özel (private) Nitelikler: x ve y koordinatları public: // açık (public) üyeler bool git(int, int); // Noktanın hareket etmesini sağlayan fonksiyon void goster(); // Noktanın koordinatlarını ekrana çıkartır bool sifir_mi(); // Noktanın (0,0) koordinatlarında olup olmadığı }; // Noktanın hareket etmesini sağlayan fonksiyon bool Nokta::git(int yeni_x, int yeni_y) { if( yeni_x > 0 && yeni_x < 500 && // yeni_x aralığında ise yeni_y > 0 && yeni_y < 300) // yeni_y aralığında ise x = yeni_x; // x koordinatına yeni değer atandı y = yeni_y; // y koordinatına yeni değer atandı return true; // atama yapıldı, hata yok } return false; // Giriş değerleri kabul edilmedi Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

68 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Yeni yazılan git fonksiyonu geriye bir mantıksal değer döndürmektedir. Bu değer sayesinde fonksiyona gönderilen koordinatların kabul edilip edilmediği anlaşılmaktadır. int main() { Nokta n1; // n1 nesnesi yaratıldı int x,y; // Tuş takımından değer okumak için iki değişken tanımlandı cout << "Noktanın gideceği koordinatları veriniz " cin >> x >> y; // Tuş takımından iki değer okunuyor if( n1.git(x,y) ) // git fonksiyonu çağırılıyor ve sonuç değerlendiriliyor n1.goster(); // Atama yapıldıysa ekrana yeni koordinatlar çıkacak else cout << "\nGirilen değerler kabul edilmemiştir"; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

69 Erişim Etiketlerinin Geçerlilik Alanları:
Bir erişim etiketi yazıldığı yerden aşağıya doğru geçerli olur. Bu etiketin altında yer alan tüm veriler ve fonksiyonlar etikette belirtilen erişim türüne sahip olurlar. Bir etiketin geçerlilik alanı, başka bir etiket yazıldığında ya da sınıfın sonuna gelindiğinde sona erer. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

70 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
C++'da struct Yapısı: C++'da struct yapısı da class ile aynı işlevi yerine getirmekte ve sınıf bildirimleri için kullanılmaktadır. struct ile class arasındaki tek fark üyelerin erişim haklarında ortaya çıkmaktadır. class bildirimlerinde aksi bildirilmedikçe üyelerin erişim tipi özeldir (private). struct bildirimlerinde ise aksi bildirilmedikçe üyelerin erişim tipi açıktır (public). Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

71 Sınıflarda Arkadaşlık (friend) İlişkisi
Bir A sınıfı oluşturulurken B sınıfı A'nın arkadaşı olarak bildirilebilir. Bu durumda B'nin tüm üye fonksiyonları erişim tipleri ne olursa olsun A'nın tüm üyelerine (public, private, protected) erişebilirler. class A{ friend class B; // B sınıfı A'nın arkadaşıdır private: // A'nın özel üyeleri int i; float f; public: // A'nın açık üyeleri void fonk1(char *c); }; class B{ // B sınıfı int j; public: void fonk2(A &s){cout << s.i;} // B, A'nın özel üyesi i'ye erişebiliyor Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

72 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Sınıflar arası arkadaşlık ilişkisi tek yönlüdür. Yukarıdaki örnekte B, A'nın arkadaşıdır ve onun tüm üyelerine erişmektedir. Ancak A, B'nin arkadaşı değildir. Bir fonksiyon da bir sınıfın arkadaşı olarak bildirilebilir. Fonksiyonlar arkadaşları oldukları sınıfların tüm üyelerine (public, private, protected) erişebilirler. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli

73 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
class Nokta{ // Nokta Sınıfı friend void sifirla(Nokta &); // Nokta sınıfının arkadaşı olan sifirla fonksiyonu int x,y; // özel (private) Nitelikler: x ve y koordinatları public: // açık (public) üyeler bool git(int, int); // Noktanın hareket etmesini sağlayan fonksiyon void goster(); // Noktanın koordinatlarını ekrana çıkartır bool sifir_mi(); // Noktanın (0,0) koordinatlarında olup olmadığı }; void sifirla (Nokta &n) // Hiçbir sınıfın üyesi değil { n.x = 0; // n'nin x elemanı sıfırlanıyor n.y = 0; // n'nin x elemanı sıfırlanıyor } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli


"Nesneye Dayalı Programlama" indir ppt

Benzer bir sunumlar


Google Reklamları