Nesneye Dayal Programlama DERS 3 Harran niversitesi Bilgisayar
Nesneye Dayalı Programlama DERS 3 Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
NESNE MODELLERİ : SINIFLAR n n 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
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). n 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 n Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Sınıflar ve Nesneler n n n 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
ÖRNEK 1 n n Ö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
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ığı }; n n n 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
Üye Fonksiyonların Gövdeleri // ***** Ü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
Ü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 n 1, n 2; // 2 adet nesne tanımlandı n 1 ve n 2 n 1. git(100, 50); // n 1 (100, 50)'ye gönderiliyor n 1. goster(); // n 1'in koordinatları ekrana çıkartılıyor n 1. git(20, 65); // n 1 (20, 65)'e gönderiliyor n 1. goster(); // n 1'in koordinatları ekrana çıkartılıyor if(n 1. sifir_mi()) // n 1 sıfır da mı? cout << "n 1 şu anda sıfır noktasındadır. " << endl; else cout << "n 1 şu anda sıfır noktasında değildir. " << endl; n 2. git(0, 0); // n 2 (0, 0)'a gönderiliyor if(n 2. sifir_mi()) // n 2 sıfır da mı? cout << "n 2 şu anda sıfır noktasındadır. " << endl; else cout << "n 2 şu anda sıfır noktasında değildir. " << endl; return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
n n Programda iki adet nesne (n 1 ve n 2) 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
Kurucu Fonksiyonlar (Constructors) n n n n 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
Parametresiz Kurucu Fonksiyonlar ( Default Constructor) n 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; } n Ana programda kurucu fonksiyonların çağrılması için özel bir deyim yazılmaz. n 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
Parametreli Kurucu Fonksiyonlar Kurucu fonksiyonlar da diğer üye fonksiyonlar gibi gerektiğinde parametre alacak şekilde tanımlanabilirler n 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 }; n 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 else y = ilk_y; } // ---- Ana Program ------int main() { Nokta n 1(20, 100), n 2(-10, 45); // Kurucu 2 kez çalışır Nokta *pn = new Nokta(10, 50); // Kurucu 1 kez çalışır. // Nokta n 3; // HATA! Parametresiz kurucu yok n 1. goster(); / n 1'in koordinatları ekrana çıkartılıyor n 2. goster(); //n 2'nin koordinatları ekrana çıkartılıyor pn->goster(); //pn 2'nin işaret ettiği nesne ekrana çıkar return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Kurucu Parametrelerine Başlangıç Değeri Verilmesi: n 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 else y = ilk_y; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
n n Bu sınıftan aşağıdaki gibi nesneler yaratılabilir. Nokta n 1(15, 75); // x=15, y=75 Nokta n 2(100); // x=100, y=0 Bu fonksiyon parametresiz bir kurucu olarak da kullanılabilir. Nokta n 3; // x=0, y=0 Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
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 } n Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
n İki kurucuya sahip bir Nokta sınıfından farklı şekillerde nesneler yaratılabilir. Nokta n 1; // Parametresiz kurucu çalışır Nokta n 2(30, 10); // Parametreli kurucu çalışır n Örnek sınıfta tek parametreli bir kurucu olmadığından aşağıdaki satır hatalıdır. Nokta n 3(10); // HATA! Bir parametreli kurucu yok Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Kurucuların Nesne Dizileri ile Kullanılması n n 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
// Kurucu Fonksiyon Nokta: : Nokta(int ilk_x, int ilk_y = 0) Nokta dizi[]= { {10} , {20} , Nokta(30, 40) }; // 3 elemanlı nesne dizisi n 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 n 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
Kurucu Fonksiyonlarda İlk Değer Atama ( Constructor Initializers) n n 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
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. class C{ // Örnek C sınıfı const int ci = 10; // HATA! sabit üye veri int x; // sabit olmayan üye veri }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
n 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 ü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
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ş }; n Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Yok Edici Fonksiyonlar ( Destructors) n n 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
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. n 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
//---- Ana Program --------int main() { String string 1("Katar 1"); String string 2("Katar 2"); string 1. goster(); string 2. goster(); return 0; // Yok edici iki defa çalışır } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Kopyalama Kurucusu (Copy Constructor) n n n 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
n n 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
n n 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
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 string 1("Katar 1"); string 1. goster(); String diger = string 1; // Kopyalanma kurucusu çalışır String baska(string 1); // Kopyalanma kurucusu çalışır diger. goster(); baska. goster(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Sabit Nesneler ve Sabit Fonksiyonlar n 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 n 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
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 }; n 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; } n 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
Statik Üyeler n n n 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
n n n 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
Nesnelerin Fonksiyonlara Parametre Olarak Aktarılması n n 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
Örnek 2: Nesnelerin fonksiyonlara değer olarak aktarılması // o 47. 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 Complex. T{ float re, im; // reel ve sanala kısımlar static unsigned int sayac; // Bu sınıftan yaratılan nesne sayisinı tutar public: Complex. T(float re_in=0, float im_in=1); // Kurucu Complex. T(const Complex. T &); // Kopyalama kurucusu Complex. T topla(Complex. T) const; // Parametre olarak nesne alan metot void goster() const; // Bilgileri ekrana çıkarır static void sifirla(){sayac=0; }// Sayacı sıfırlayan static metot ~Complex. T(); // Yok edici }; 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. Complex. T: : Complex. T(float re_in, float im_in) { re=re_in; im=im_in; sayac++; cout<< endl << "Kurucu calisti. "; cout<< "Nesne sayisi = "<< sayac; } // Kopyalama Kurucusu // Nesnenin verilerini kopylar // Yaratılan nesne sayisinı arttırır Complex. T: : Complex. T(const Complex. T &c) { re=c. re; im=c. im; sayac++; cout<< endl << "Kopyalama kurucusu calisti. "; cout<< "Nesne sayisi = "<< sayac; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli // Nesne sayisi arttırıldı // Elemanlar kopyalanıyor // Nesne sayisi arttırıldı
// İ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! Complex. T: : topla(Complex. T c) const { cout<< endl << "Toplama metodu calisiyor"; Complex. T 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 ilgili bilgileri ekrana çıkaran metot void Complex. T: : goster() const { cout << endl << "re= " << re << " , im= " << im; cout << " Nesne sayisi= " << sayac; } // Yok edici fonksiyon // Yaratrılan nesne sayisinı bir azaltır Complex. T: : ~Complex. T() { sayac--; azaltıldı cout<< endl << "Yok edici calisti. "; cout<< "Nesne sayisi = "<< sayac; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli // Nesne sayisi
unsigned int Complex. T: : sayac; // static sayac icin bellekte yer ayrıldı //------ Ana program ------int main() { Complex. T: : sifirla(); sıfırlandı Complex. T z 1, z 2, z 3; yarıtıldı z 3=z 1. topla(z 2); işlemi yapılıyor. z 3. goster(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli // sayac // Üç adet nesne // z 3 = z 1 + z 2
n n n 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
Örnek 3: Nesnelerin fonksiyonlara referans olarak aktarılması // o 48. 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 Complex. T{ float re, im; // reel ve sanala kısımlar static unsigned int sayac; // Bu sınıftan yaratılan nesne sayisinı tutar public: Complex. T(float re_in=0, float im_in=1); // Kurucu Complex. T(const Complex. T &); // Kopyalama kurucusu Complex. T topla(const Complex. T &) 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 ~Complex. T(); // Yok edici }; 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. Complex. T: : Complex. T(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 Complex. T: : Complex. T(const Complex. T &c) { re=c. re; // Elemanlar kopyalanıyor im=c. im; sayac++; // Nesne sayisi arttırıldı cout<< endl << "Kopyalama kurucusu calisti. "; cout<< "Nesne sayisi = "<< sayac; } 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. Complex. T: : topla(const Complex. T & c) const { cout<< endl << "Toplama metodu calisiyor"; Complex. T 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 ilgili bilgileri ekrana çıkaran metot void Complex. T: : goster() const { cout << endl << "re= " << re << " , im= " << im; cout << " Nesne sayisi= " << sayac; } // Yok edici fonksiyon // Yaratrılan nesne sayisinı bir azaltır Complex. T: : ~Complex. T() { sayac--; azaltıldı cout<< endl << "Yok edici calisti. "; cout<< "Nesne sayisi = "<< sayac; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli // Nesne sayisi
unsigned int Complex. T: : sayac; // static sayac icin bellekte yer ayrıldı //------ Ana program ------int main() { Complex. T: : sifirla(); sıfırlandı Complex. T z 1, z 2, z 3; yarıtıldı z 3=z 1. topla(z 2); işlemi yapılıyor. z 3. goster(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli // sayac // Üç adet nesne // z 3 = z 1 + z 2
Fonksiyonlardaki Geçici Nesnelerin Azaltılması n n n Ö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. Complex. T: : topla(const Complex. T & 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 Complex. T(gecici_re, gecici_im); // Nesne yaratılıyor, kurucu canlanır } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Ö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 Complex. T{ float re, im; // reel ve sanal kısımlar static unsigned int sayac; // Bu sınıftan yaratılan nesne sayisinı tutar public: Complex. T(float re_in=0, float im_in=1); // Kurucu Complex. T(const Complex. T &); // Kopyalama kurucusu Complex. T topla(const Complex. T &) 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 ~Complex. T(); // Yok edici }; 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. Complex. T: : Complex. T(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 Complex. T: : Complex. T(const Complex. T &c) { re=c. re; // Elemanlar kopyalanıyor im=c. im; sayac++; // Nesne sayisi arttırıldı cout<< endl << "Kopyalama kurucusu calisti. "; cout<< "Nesne sayisi = "<< sayac; } 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. Complex. T: : topla(const Complex. T & 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 Complex. T(gecici_re, gecici_im); // Nesne yartılıyor, kurucu canlanır } // Nesne ilgili bilgileri ekrana çıkaran metot void Complex. T: : goster() const { cout << endl << "re= " << re << " , im= " << im; cout << " Nesne sayisi= " << sayac; } // Yok edici fonksiyon // Yaratrılan nesne sayisinı bir azaltır Complex. T: : ~Complex. T() { sayac--; azaltıldı cout<< endl << "Yok edici calisti. "; cout<< "Nesne sayisi = "<< sayac; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli // Nesne sayisi
unsigned int Complex. T: : sayac; // static sayac icin bellekte yer ayrıldı //------ Ana program ------int main() { Complex. T: : sifirla(); sıfırlandı Complex. T z 1, z 2, z 3; yarıtıldı z 3=z 1. topla(z 2); işlemi yapılıyor. z 3. goster(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli // sayac // Üç adet nesne // z 3 = z 1 + z 2
İç içe nesneler: Nesnelerin başka sınıfların üyesi olması n n n 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 (Complex. Kes) 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
n Burada Complex. Kes 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
Ö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
Örnek olarak hazırlanan Complex. Kes sınıfı: // Elemanları bayağı kesir olan karmaşık sayıları tanımlayan sınıf class Complex. Kes{ Kesir re, im; // üye nesneler public: Complex. Kes(int, int); // Kurucu void goster() const; }; // Kurucu fonksiyon // Önce üye nesnelerin kurucularına gerekli parametreler gönderiliyor Complex. Kes: : Complex. Kes(int re_in, int im_in) : re(re_in, 1), im(im_in, 1) {. . } Üye nesnelerin kurucuları canlanır // Karmaşık sayı ekrana çıkarılıyor void Complex. Kes: : goster() const int main() // Ana program { { re. goster(); Complex. Kes ck(2, 5); // Bir karmaşık im. goster(); 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
Değerlendirme: Sınıflar ve nesneler hakkında bu aşamaya kadar öğrendiklerimizi değerlendirdiğimizde şu sonuçlara varabiliriz: n Sınıflar 'aktif' veri tipleridir. Bu tiplerden nesneler tanımlanır. Nesnelere mesajlar gönderildiğinde nesneler bir davranışta bulunarak cevap verirler. n 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
Metotların inline Fonksiyon (Makro) Olarak Tanımlanmaları: n Ö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
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
Nesnelerin Dinamik Olarak Yaratılması: n n 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 (pn 1 ve pn 2) 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
int main() { Nokta*pn 1 = new Nokta; //pn 1'in gösterdiği nesne için bellekten yer alındı Nokta*pn 2 = new Nokta; //pn 2'nin gösterdiği nesne için bellekten yer alındı pn 1 ->git(50, 50); //pn 1'in gösterdiği nesneye git mesajı pn 1 ->goster(); //pn 1'in gösterdiği nesneye goster mesajı pn 2 ->git(100, 150); //pn 2'nin gösterdiği nesneye git mesajı if(pn 2 ->sifir_mi()) // pn 2'nin gösterdiği nesne sıfır da mı? cout << "pn 2'nin nesnesi şu anda sıfır noktasındadır. " << endl; else cout << "pn 2'nin nesnesi şu anda sıfır noktasında değildir. " << endl; delete pn 1; // Dinamik bellekten alınan yerler geri veriliyor delete pn 2; return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Nesnelerin Dizi Olarak Yaratılması: n 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
Sınıf Üyelerine Erişimin Denetlenmesi n n 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
n 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
n n n 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
n n n 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
Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
n Örnek olarak Nokta sınıfından üretilen noktaların hareket alanlarının x ekseninde 0500, y ekseninde ise 0 -300 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 0 -500 aralığında ise yeni_y > 0 && yeni_y < 300) // yeni_y 0 -300 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
n 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 n 1; // n 1 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( n 1. git(x, y) ) // git fonksiyonu çağırılıyor ve sonuç değerlendiriliyor n 1. goster(); // Atama yapıldıysa ekrana yeni koordinatlar çıkacak else cout << "n. Girilen değerler kabul edilmemiştir"; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd. Doç. Dr. Nurettin Beşli
Erişim Etiketlerinin Geçerlilik Alanları: n 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
C++'da struct Yapısı: n n n 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
Sınıflarda Arkadaşlık (friend) İlişkisi n 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 fonk 1(char *c); }; class B{ // B sınıfı int j; public: void fonk 2(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
n n 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
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
- Slides: 73