Bölüm 14 İleri C Konuları

Benzer belgeler
C++ Giriş Ders 1 MSGSU Fizik Bölümü Ferhat ÖZOK Kullanılacak kaynak: Published by Juan Soulié

BĠLGĠSAYAR PROGRAMLAMA II C++ Programlamaya GiriĢ Published by Juan Soulié

işlemler bittikten sonra dosyaların kapatılması uygun olacaktır. Bunun için, fclose(fin);

BMT 101 Algoritma ve Programlama I 5. Hafta. Yük. Müh. Köksal Gündoğdu 1

NESNEYE YÖNELİK PROGRAMLAMA C++ a Giriş

Bölüm 2 - C ile Programlamaya Giriş

1 PROGRAMLAMAYA GİRİŞ

BMT 106 Algoritma ve Programlama II Bahar Dönemi

3/7/2011. ENF-102 Jeoloji 1. Tekrar -- Değişken Tanımlamaları (Definition) ve Veri Türleri (Data Type) Veri Tanımları ve Mantıksal Đşlemler

B02.6 Karar Verme, Eşitlik ve Bağıntı Operatörleri

Dr. Fatih AY Tel: fatihay@fatihay.net

Eln 1002 Bilgisayar Programlama II

Sınav tarihi : Süre : 60 dak. a) strstr b) strchr c) strcat d) strcpy e) strlen. a) b) d) e) 0

Değişkenler tanımlanırken onlara ne tür veriler atanabileceği de belirtilir. Temel veri türleri oldukça azdır:

PROGRAMLAMAYA GİRİŞ DERS 2

ELN1001 BİLGİSAYAR PROGRAMLAMA I

Fonksiyonlar. C++ ve NESNEYE DAYALI PROGRAMLAMA 51. /* Fonksiyon: kup Bir tamsayının küpünü hesaplar */ long int kup(int x) {

C# Yazım Kuralları ERCİYES. Ü. BİLGİSAYAR M. COMPUTER PROGRAMMING II 1 FEHİM KÖYLÜ

ELN1002 BİLGİSAYAR PROGRAMLAMA 2

10/17/2007 Nesneye Yonelik Programlama 3.1

C++ Dersi: Nesne Tabanlı Programlama

Örnek: İki fonksiyondan oluşan bir program. Fonksiyon Tanımı

BÖLÜM 4: DEĞİŞKENLER, SABİTLER VE OPERATÖRLER

Fonksiyonlar -Genel Test- A

BLM-111 PROGRAMLAMA DİLLERİ I. Ders-8 Değişken Tipleri ve Temel Giriş/Çıkış İşlemleri

Sınav tarihi : Süre : 60 dak.

Sınav tarihi : Süre : 60 dak. a) ABCDE b) BCDE c) ABCD d) kod hatalı e) BCD

DOSYA İŞLEMLERİ Programlama dilleri hafta -

C++ Dersi: Nesne Tabanlı Programlama

String ve Karakter Dizileri. Yrd. Doç. Dr. Fehim KÖYLÜ Erciyes Üniversitesi Bilgisayar Mühendisliği Bölümü

KONU 7: DOSYA İŞLEME ( File Processing )

BLM-112 PROGRAMLAMA DİLLERİ II. Ders-8 Dosya İşlemleri-1. Yrd. Doç. Dr. Ümit ATİLA

Eln 1001 Bilgisayar Programlama I

Hafta 13 Fonksiyonlar

Algoritma ve Programlama: Karar Yapıları ve Döngüler

Temel Bilgisayar Bilimleri Ders Notu #4-2. kısım

BİLGİSAYAR MÜHENDİSLİĞİ ALGORİTMA VE PROGRAMLAMA II 2.HAFTA SWİTCH (CASE), SAYAÇLAR, DÖNGÜLER,

Bil101 Bilgisayar Yazılımı I. M. Erdem ÇORAPÇIOĞLU Bilgisayar Yüksek Mühendisi

C++ Statements. { ve } arasında ifade edilen bir dizi statement bir compound statement (birleşik ifade) oluşturur.

10. DOSYA GİRİŞ ÇIKIŞ FONKSİYONLARI

İçerik. Java da İşleçler, İşleçler. Aritmetik İşleçler - 1. Aritmetik İşleçler - 2. Geçen ders: Bu ders: BS-515 Nesneye Yönelik Programlama

ESM-361 Mikroişlemciler. 3. Hafta Ders Öğretim Üyesi Dr.Öğr.Üyesi Ayşe DEMİRHAN

C PROGRAMLAMA D İ L İ

Pointer Kavramı. Veri Yapıları

NESNEYE YÖNELİK PROGRAMLAMA SINIFLAR

BLM-111 PROGRAMLAMA DİLLERİ I. Ders-12 Fonksiyonlar. Yrd. Doç. Dr. Ümit ATİLA

BMT 101 Algoritma ve Programlama I 6. Hafta. Yük. Müh. Köksal Gündoğdu 1

Genel Programlama II

Java da İşleçler, Ders #3 (4 Kasım 2009)

ALGORİTMA VE PROGRAMLAMA II

Diziler. Yrd.Doç.Dr.Bülent ÇOBANOĞLU

C++ Dersi: Nesne Tabanlı Programlama

YAPILAR BİRLİKLER SAYMA SABİTLERİ/KÜMELERİ. 3. Hafta

/ C Bilgisayar Programlama Final Sınavı Test Soruları. Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : , 60 dak.

ENF102 TEMEL BİLGİSAYAR BİLİMLERİ VE C/ C++ PROGRAMLAMA DİLİ. Gazi Üniversitesi Mühendislik Fakültesi Bilgisayar Mühendisliği Bölümü

Programlama Dilleri 1. Ders 12: Belirleyiciler ve Niteleyiciler

Ders 2: Veri Tipleri, Değişkenler ve Sabitler

Temel Dosya İşlemleri. Kütük Organizasyonu 1

C Programlama Dilininin Basit Yapıları

Fonksiyonlar (Altprogram)

Programlama Dilleri. C Dili. Programlama Dilleri-ders02/ 1

şeklinde tanımlanmıştır. O halde, dosyaları daha önceki bilgilerimizi kullanarak FILE *Dosya1, *Dosya2;

Temel Giriş/Çıkış Fonksiyonları

C Programlama Dilinde Değişkenler

ELN1001 BİLGİSAYAR PROGRAMLAMA I

Programlama Dillerinde Kullanılan Veri Tipleri

Karakter katarları ile ilgili fonksiyonlar içerir Yerel kayan noktalı sayılar tanımlanır

Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : dak.

Örnek 4: Örnek Özyinelemeli fonksiyon örneği Bölüm 9. C++ programlama dilinde Nesne ve sınıf

Yrd. Doç. Dr. Caner ÖZCAN

Görsel Programlama DERS 03. Görsel Programlama - Ders03/ 1

BİL-142 Bilgisayar Programlama II

Metin Dosyaları. Metin Dosyaları Dosya Açma ve Kapama Dosya Okuma ve Yazma Rastgele Erişim Standart Girdi/Çıktı Hata Kontrolü

C++ Dersi: Nesne Tabanlı Programlama

NESNEYE YÖNELİK PROGRAMLAMA

BASİT C PROGRAMLARI Öğr.Gör.Dr. Mahmut YALÇIN

NESNE YÖNELİMLİ PROGRAMLAMA HAFTA # 2

Bölüm 11. Soyut veri tipleri ve kapsülleme kavramları ISBN

Giris {\} /\ Suhap SAHIN Onur GÖK

Nesne Yönelimli Programlama

Göstericiler (Pointers)

Nesne Tabanlı Programlama

Yrd. Doç. Dr. Caner ÖZCAN

int printf (const char *format [, argument,...]);

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

C PROGRAMLAMA DİLİNE GİRİŞ

Temel Bilgisayar Programlama

ALGORİTMA VE PROGRAMLAMA I DERS NOTU#10

BTEP243 Ders 3. class Yazım Kuralı:

Çoktan Seçmeli Değerlendirme Soruları Akış Şemaları İle Algoritma Geliştirme Örnekleri Giriş 39 1.Gündelik Hayattan Algoritma Örnekleri 39 2.Say

ELN1001 BİLGİSAYAR PROGRAMLAMA I

Dizi nin Önemi. Telefon rehberindeki numaralar, haftanın günleri gibi v.b.

BÖLÜM 11: YAPISAL VERİ TİPLERİ

Nesne tabanlı programlama nesneleri kullanan programlamayı içerir. Bir nesne farklı olarak tanımlanabilen gerçek dünyadaki bir varlıktır.

Programlama Dilleri. C Dili. Programlama Dilleri-ders08/ 1

mod ile açılacak olan dosyanın ne amaçla açılacağı belirlenir. Bunlar:

BİLGİSAYAR TEMELLERİ VE PROGRAMLAMAYA GİRİŞ

FONKSİYONLAR. Gerçek hayattaki problemlerin çözümü için geliştirilen programlar çok büyük boyutlardadır.

NESNEYE YÖNELİK PROGRAMLAMA

Veri Yapıları Lab Notları 1

Transkript:

Bölüm 14 İleri C Konuları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 1 İçerik 14.1 Giriş 14.2 UNIX ve DOS Sistemlerinde Girdi/Çıktı Yönlendirme 14.3 Değişken Uzunluklu Argüment Listesi 14.4 Komut-Satırı Argümentleri Kullanma 14.5 Çoklu Kaynak Dosyalı Programların Derlenmesi 14.6 exit ve atexit ile Program Sonlandırma 14.7 volatile Tipi Niteleyici 14.8 Integer ve Floating-Point Sabitleri İçin Sonekler 14.9 Dosyalar 14.10 Sinyal Kontrolü 14.11 calloc ve realloc ile Dinamik Bellek Düzenleme 14.12 Koşulsuz Branş: goto

14.1 Giriş Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 2 Bir çok ileri düzey konulardan bahsedilecek Özel olarak işletim sistemleri Genellikle UNIX veya DOS

14.2 UNIX ve DOS Sistemlerinde Girdi/Çıktı (I/O) Yönlendirme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 3 Standard I/O klavye ve ekran Girdi ve çıktıyı yeniden yönlendir Yönlendirme sembolü(<) İşletim sistemi özelliği, C özelliği değil UNIX ve DOS $ veya % komut satırını temsil eder Örnek: $ Program < girdi Girdi değerlerini yazmak yerine, dosyadan okur ( ) komutu Bir programın çıktısı diğer bir programın girdisi olur $ Program1 Program2 Program1 in çıktısı Program2 ye girdi olarak gider

14.2 UNIX ve DOS Sistemlerinde Girdi/Çıktı (I/O) Yönlendirme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 4 Yönlendirilmiş Çıktı (>) Bir programın çıktısının nereye gideceğini belirler Örnek: $ Program > dosyam Çıktı dosyam dosyasına gider (önceki içeriği siler) Ekleme Çıktısı (>>) Çıktıyı dosyanın sonuna ekler(önceki içeriği korur) Örnek: $ Program >> dosyam Çıktı dosyam dosyasının sonuna eklenir

14.3 Değişken Uzunluklu Argüment Listesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 5 Argüment sayısı belli olmayan fonksiyonlar <stdarg.h> yükle Parametre listesinin sonuna (...) yaz En az bir tanımlı parametre gereklidir Örnek: double fonksiyon( int i,... ); Noktalar değişken uzunluklu argüment listeli fonksiyonun sadece prototipinde kullanılır printf çoklu argüment alan bu tipten bir fonksiyondur printf prototipi int printf( const char* format,... ); şeklinde tanımlanır

14.3 Değişken Uzunluklu Argüment Listesi Makrolar ve değişken argümentlerin tanımları header (stdarg.h) va_list Tip belirteci, (va_list argümentleri) gereklidir va_start( argümentler, diğer değişkenler) Parametreleri verir, kullanımdan önce gerekli va_arg( argümentler, tip) va_arg her çağrıldığında bir parametre gönderir Otomatik olarak bir sonraki parametreyi işaret eder va_end( argümentler ) Fonksiyonun normal dönmesine yardım eder Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 6

14.3 Değişken Uzunluklu Argüment Listesi 2 Değişken uzunluklu argüment listesi kullanma */ 3 #include <stdio.h> 4 #include <stdarg.h> 5 6 double ortalama( int,... ); 7 8 int main() 9 { 10 double w = 37.5, x = 22.5, y = 1.7, z = 10.2; 11 12 printf( "%s%.1f\n%s%.1f\n%s%.1f\n%s%.1f\n\n", 13 "w = ", w, "x = ", x, "y = ", y, "z = ", z ); 14 printf( "%s%.3f\n%s%.3f\n%s%.3f\n", 15 " w ve x in ortalaması ", 16 ortalama( 2, w, x ), 17 " w, x ve y nin ortalaması ", 18 ortalama( 3, w, x, y ), 19 " w, x,y ve z nin ortalaması ", 20 ortalama( 4, w, x, y, z ) ); 21 22 return 0; 23 } 24 25 double ortalama( int i,... ) 26 { 27 double toplam = 0; 28 int j; 29 va_list ap; 1. Yükle <stdarg.h> 1.1 Fonksiyon prototipi (değişken uzunluklu arg. listeli) 1.2 Değişkenleri belirle 2. Fonksiyon çağır 3. Fonksiyon tanımı 3.1 ap (va_list nesnesi) oluştur 3.2 ap belirle (va_start(ap, i)) İLERİ C KONULARI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 7

14.3 Değişken Uzunluklu Argüment Listesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 8 30 31 va_start( ap, i ); 32 33 for ( j = 1; j <= i; j++ ) 34 toplam += va_arg( ap, double ); 35 36 va_end( ap ); 37 return toplam / i; 38 } 3.3 Argümentlere eriş va_arg(ap, double) 3.4 fonksiyon sonlandır va_end(ap); return toplam/1; w = 37.5 x = 22.5 y = 1.7 z = 10.2 w ve x in ortalaması 30.000 w, x ve y nin ortalaması 20.567 w x, y ve z nin ortalaması 17.975

14.4 Komut-Satırı Argümentleri Kullanma Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 9 DOS veya UNIX de argümentleri main e aktar Main tanımı int main( int argc, char *argv[] ) int argc Aktarılan argüment sayısı char *argv[] String dizisi Argüment adlarına sıralı olarak sahiptir argv[ 0 ] ilk argümenttir Örnek: $ copy input output argc: 3 argv[ 0 ]: "copy" argv[ 1 ]: "input" argv[ 2 ]: "output"

1 /* Fig. 14.3: fig14_03.c 2 Komut satırı argümentleri kullanma */ 3 #include <stdio.h> 4 5 int main( int argc, char *argv[] ) 6 { 7 FILE *girdidosyaptr, *ciktidosyaptr; 8 int c; 9 10 if ( argc!= 3 ) 14.4 Komut-Satırı Argümentleri Kullanma 11 printf( Kullanım: kopya girdidosyası çıktıdosyası\n" ); 12 else argv[2] 3. argümenttir, ve yazılmaktadır 13 if ( ( girdidosyaptr = fopen( argv[ 1 ], "r" ) )!= NULL ) 14 15 if ( ( ciktidosyaptr = fopen( argv[ 2 ], "w" ) )!= NULL ) 16 17 while ( ( c = fgetc( girdidosyaptr ) )!= EOF ) 18 fputc( c, ciktidosyaptr ); 19 20 else 21 printf(" Dosya \"%s\" açılamıyor EOF a \n", kadar döngü. argv[ fgetc 2 ] ); ile infileptr den bir karakter al ve fputc ile outfileptr ye yaz 22 23 else 24 printf( Dosya \"%s\" açılamıyor \n", argv[ 1 ] ); 25 26 return 0; 27 } main deki argc ve argv[] ye dikkat et argv[1] 2. argümenttir ve okunmaktadır. İLERİ C KONULARI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 10

14.5 Çoklu Kaynak Dosyalı Programların Derlenmesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 11 Çok dosyalı programlar Fonksiyon tanımı tek bir dosyada olmalı (parçalanamaz) Global değişkenler aynı dosyadaki fonksiyonlara erişebilir Global değişkenler kullanıldıkları her dosyada tanımlanmalıdır Örnek: Eğer birglobal tamsayısı bir dosyada tanımlandı ise Bunu bir başka dosyada kullanmak için extern int birglobal; dosyaya eklenmelidir extern Değişkenin bir başka dosyada tanımlandığını belirtir Fonksiyon prototipleri extern olmadan diğer dosyalarda kullanılabilir Fonksiyonu kullanan her dosyada bir prototip bulundur

14.5 Çoklu Kaynak Dosyalı Programların Derlenmesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 12 static anahtar kelimesi Değişkenin sadece tanımlandığı dosyada kullanılacağını belirtir Çoklu dosyalı programlar Bir dosyada küçük bir değişiklik yapıldıysa tümünü yeniden derlemek gereksizdir Sadece değiştirilen dosyalar derlenebilir İşlem sisteme bağlıdır UNIX: make komutu

14.6 exit ve atexit ile Program Sonlandırma exit fonksiyonu Programın sonlanmasını sağlar Parametreler EXIT_SUCCESS veya EXIT_FAILURE sembolik sabitleri Uygulama-tanımlı bir değer gönderir Örnek: exit( EXIT_SUCCESS ); atexit fonksiyonu atexit( çalıştırılacak fonksiyon ); Programın başarı ile sonlanması sonucunda çalıştırılacakfonksiyon u işleme sokmak için kaydeder atexit programı kendisi sonlandırmaz 32 fonksiyona kadar kaydedebilir (çoklu atexit() deyimleri) Fonksiyonlar sondan başa kayıt sırası ile çağrılır Çağrılan fonksiyonlar argüment almaz veya birşey göndermez Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 13

1 /* Fig. 14.4: fig14_04.c 14.6 exit ve atexit ile Program Sonlandırma 2 exit ve atexit fonksiyonları kullanımı*/ 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 void yaz( void ); 7 8 int main() 9 { 10 int cevap; 11 12 atexit( yaz ); /* yaz fonksiyonunu kaydet */ 13 printf("exit fonksiyonu ile programı kapatmak için 1 gir" 14 "\n Programı normal sonlandırmak için 2 gir\n" ); 15 scanf( "%d", &cevap ); 16 17 if ( cevap == 1 ) { 18 printf( "\n Programı " 19 "exit ile sonlandırıyor\n" ); 20 exit( EXIT_SUCCESS ); 21 } 22 23 printf( "\nprogramı main sonuna" 24 " ulaşarak sonlandırıyor \n" ); 25 return 0; 26 } 27 28 void yaz( void ) 29 { 30 printf(" Program sonunda yaz fonksiyonunu " 31 çalıştırıyor\nprogram sonlandı.\n" ); 1. Register fonksiyonu yaz; atexit kullanarak 2. Kullanıcı girdisi 3. Çıktı 3.1 fonksiyon tanımı İLERİ C KONULARI Nuri 32 ÖZALP } (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 14

14.6 exit ve atexit ile Program Sonlandırma Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 15 exit fonksiyonu ile programı kapatmak için 1 gir Programı normal sonlandırmak için 2 gir : 1 Programı exit ile sonlandırıyor Program sonunda yaz fonksiyonunu çalıştırıyor Program sonlandı exit fonksiyonu ile programı kapatmak için 1 gir Programı normal sonlandırmak için 2 gir : 2 Programı main sonuna ulaşarak sonlandırıyor Program sonunda yaz fonksiyonunu çalıştırıyor Program sonlandı

14.7 volatile Tipi Niteleyici Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 16 volatile (Değişken tip) niteleyicisi Değişken program dışında değiştirilebilir Değişken programın kontrolünde değildir Değişken optimize edilemez Const tipinin zıttı

14.8 Integer ve Floating-Point Sabitleri İçin Sonekler Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 17 C sabitler için sonekler sağlar unsigned integer u veya U long integer l veya L unsigned long integer ul veya UL float f veya F long double l veya L Örnekler: 174u 467L 3451ul Eğer integer sabitte ek yok ise, tipi o değeri yükleyebilecek ilk tiple belirlenir(sırası: int, long int, unsigned long int) Eğer floating point de ek yok ise tipi otomatik olarak double dır

14.9 Dosyalar (Ekstra) C binary (ikili) dosyaları işleyebilir Her sistem binary dosyayı desteklemez Binary mod desteklenmiyorsa dosyalar tekst dosyası olarak açılır Hız bellek yeri ve uyumluluk koşulları gerektiriyorsa binary dosya kullanılmalıdır Diğer durumlarda tekst dosyası tercih edilir Doğal taşınabilirliği, veri incelemesi için satandart araçları olduğundan tmpfile fonksiyonu "wb+" modunda geçici bir dosya açar Bazı sistemler geçici dosyaları tekst dosyası olarak işlerler Geçici dosyalar fclose ile kapatılmadıkça veya program kapanmadıkça var olur rewind fonksiyonu Dosya pointer-ını dosyanın başına getirir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 18

14.9 Dosyalar (Ekstra) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 19 Dosya açma modları: Mod rb wb ab rb+ wb+ ab+ Açıklama Okumak için binary dosya aç. Yazmak için binary dosya oluştur. Dosya mevcut ise, içeriğini yok eder. Ekle; sonuna yazmak için bir binary dosya aç veya oluştur. Yenilemek için binary dosya aç (okuma ve yazma). Yenilemek için bir binary dosya oluştur. Dosya mevcut ise, içeriğini yok eder. Ekle; yenilemek için binary dosya aç veya oluştur; yazım dosya sonuna yapılır

14.10 Sinyal Kontrolü Sinyal Beklenmeyen olay, programı durdurur müdahale (<ctrl> c), illegal komut, kesimleme ihlali, sonlanma sırası, floating-point durumları (sıfıra bölme, çok büyük reel sayıları çarpma) signal fonksiyonu Beklenmedik olayları yakalar Header <signal.h> İki argüment alır; bir sinyal numarası ve sinyal kontrol fonksiyonuna bir pointer raise fonksiyonu Bir tamsayı sinyal numarası alır ve sinyal oluşturur Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 20

14.10 Sinyal Kontrolü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 21 signal.h de tanımlı sinyaller Sinyal SIGABRT SIGFPE SIGILL SIGINT SIGSEGV SIGTERM Açıklama Beklenmedik program sonlanması (abort a bir çağrım gibi). Sıfıra bölme gibi, hatalı bir aritmetik işlem. Bir illegal komutun yakalanması. Bir interaktif dikkat sinyali alınması. Belleğe geçersiz bir erişim. Programa gönderilen bir durdurma istemi.

1 /* Fig. 14.8: fig14_08.c 2 Sinyal kontrol kullanımı */ 3 #include <stdio.h> 4 #include <signal.h> 5 #include <stdlib.h> 6 #include <time.h> 7 8 void sinyal_kontrol( int ); 9 10 int main() 11 { 12 int i, x; 13 14 signal( SIGINT, sinyal_kontrol ); 15 srand( clock() ); 16 17 for ( i = 1; i <= 100; i++ ) { 18 x = 1 + rand() % 50; 19 20 if ( x == 25 ) 21 raise( SIGINT ); 22 23 printf( "%4d", i ); 24 25 if ( i % 10 == 0 ) 26 printf( "\n" ); 27 } 28 29 return 0; 30 } 31 14.10 Sinyal Kontrolü SIGINT sinyal tipi oluştuğunda signal, sinyal_kontrol fonksiyonunu çağırır 1. Fonksiyon prototipi 2. random sayı seç 2.1 x == 25 ise sinyali yükselt 3. Fonksiyon tanımı İLERİ C KONULARI Nuri 32 ÖZALP void (ANKARA sinyal_kontrol( ÜNİVERSİTESİ) İLERİ PROGRAMLAMA int sinyaldegeri ) 22

14.10 Sinyal Kontrolü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 23 33 { 34 int cevap; 35 36 printf( "%s%d%s\n%s", 37 "\n Kesme sinyali ( ", sinyaldeğeri, " ) alındı.", 38 Devam etmek istermisiniz ( 1 = evet veya 2 = hayır )? " ); 39 40 scanf( "%d", &cevap ); Programı sonlandırmak için kullanıcı seçimi 41 42 while ( cevap!= 1 && cevap!= 2 ) { 43 printf( "( 1 = evet veya 2 = hayır )? " ); Sinyal kontrol signal i tekrar çağırarak yenilenir 44 scanf( "%d", &cevap ); 45 } 46 47 if ( cevap == 1 ) 48 signal( SIGINT, sinyal_kontrol ); 49 else 50 exit( EXIT_SUCCESS ); 51 } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

14.10 Sinyal Kontrolü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 24 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 Kesme sinyali ( 2 ) alındı. Devam etmek istermisiniz ( 1 = evet veya 2 = hayır )? 1 94 95 96 Kesme sinyali ( 2 ) alındı. Devam etmek istermisiniz ( 1 = evet veya 2 = hayır )? 1 97 98 99 100

14.11 calloc ve realloc ile Dinamik Bellek Düzenleme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 25 Dinamik Bellek Düzenleme Dinamik diziler oluşturabilir calloc( üyesay, boyut ) üyesay üye sayısı boyut her bir üyenin boyutu Dinamik bir diziye pointer gönderir realloc( nesneyepointer, yeniboyut) nesneyepointer düzenlenecek nesneye pointer yeniboyut nesnenin yeni boyutu Düzenlenmiş belleğe pointer gönderir Yeri düzenleyemezse NULL gönderir Eğer yeniboyut 0 ise işaretlenen nesne serbest bırakılır Eğer nesneyepointer 0 ise malloc gibi davranır

14.12 Koşulsuz Branş: goto Yapısallaşmamış programlama Zorunlu ise kullan Döngüden çıkmak için false oluşmasını beklemek yerine break ile çık goto deyimi Akış kontrolünü belirtilen etiketten başlatır Etiket bir belirleyicidir (örneğin basla:) İçiçe döngülerden hızla çıkmak için goto basla; Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 26

14.12 Koşulsuz Branş: goto 1 /* Fig. 14.9: fig14_09.c 2 goto kullanımı*/ 3 #include <stdio.h> 4 5 int main() 6 { 7 int say = 1; 8 9 basla: /* etiket */ 10 if ( say > 10 ) 11 goto son; 12 13 printf( "%d ", say ); 14 ++say; 15 goto basla; 16 17 son: /* etiket */ 18 putchar( '\n' ); 19 20 return 0; 21 } 1 2 3 4 5 6 7 8 9 10 Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA İLERİ C KONULARI 27

Bölüm 15 - C++ " Daha İyi Bir C " Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 1 İçerik 15.1 Giriş 15.2 C++ 15.3 Bir Basit Program: İki Tamsayıyı Toplama 15.4 C++ Standard Kütüphanesi 15.5 Header Dosyaları 15.6 Satıriçi (Inline) Fonksiyonları 15.7 Referanslar ve Referans Parametreleri 15.8 Default Argumentler ve Boş Parametre Listesi 15.9 Tek Operandlı(Unary) Hedef Karar Operatörü 15.10 Fonksiyon Yüklemeleri 15.11 Fonksiyon Şablonları

15.1 Giriş Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 2 İlk 14 bölüm Yordamsal programlama C ile yukarıdan-aşağı programlama dizaynı Bölüm 15-23 C++ Nesne tabanlı programlama (sınıflar, nesneler, gruplama) Nesne tabanlı programlama (kalıt, polimorfism) Genel programlama (sınıf (class) ve fonksiyon şablonları)

15.2 C++ C++ Bir çok C özelliğini geliştirdi Nesne tabanlı kapasiteye sahip Yazılım kalitesini ve tekrar kullanılabilirliğini artırır Bell Labs de Bjarne Stroustrup geliştirdi "sınıflı C " olarak adlandırılır C++ (artırma operatörü) - C nin gelişmiş sürümü C den çok üstün C++ derleyicisi C programlarını da derleyebilir C programlarını adım adım C++ a genişletir ANSI C++ Son sürümü http://www.ansi.org/ http://www.cygnus.com/misc/wp/ de bedava Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 3

15.3 Bir Basit Program: İki Tamsayıyı Toplama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 4 Dosya uzantısı C dosyası:.c C++ dosyası:.cpp (kullandığımız),.cxx,.c (büyük harf) Farkları C++ da " açıklamlar için" // kullan Örneğin: // açıklama yazısı <iostream> - girdi çıktı (input/output) akışı header dosyası Gönderme tipleri tüm fonksiyonlar gönderme tipini belirtmelidir C de gerek yok, fakat C++ da gerekli C++ değişkenler hemen hemen her yerde deklare edilebilir C de herhangi bir işletilebilir deyimden önce blok olarak verilir

15.3 Bir Basit Program: İki Tamsayıyı Toplama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 5 C++ da Input/Output Karakter akışları(streams) ile gerçeklenir Akışlar input/output nesnesine gönderilir Output std::cout - standard çıktı akışı (ekrana bağlanır) << stream ekleme operatörü std::cout << merhaba"; merhaba" kelimesini std::cout a ekler yani yazar Input std::cin - standard input nesnesi (klavyeye bağlanır) >> stream alma operatörü std::cin >> değişken; Klavyeden akışı alır ve değişken e aktarır

15.3 Bir Basit Program: İki Tamsayıyı Toplama std::endl satır sonu" Akış düzenleyici yeni satır yazar ve çıktı desteğini temizler Bazı sistemler yazılacak yeterli tekst olana kadar çıktıyı görüntülemez std::endl tekstin görünmesini sağlar using deyimleri std:: önek in kaldırılmasına izin verir Sonra tartışılacak Taşırma Çoklu << veya >> operatörleri tek bir deyimde std::cout << Merhaba " << sınıf" << std::endl; Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 6

15.3 Bir Basit Program: İki Tamsayıyı Toplama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 7 1 // Fig. 15.1: fig15_01.cpp 2 // Toplama programı 3 #include <iostream> 4 5 int main() 6 { 7 int tam1, tam2, toplam; // deklarasyon 8 9 std::cout << İlk tamsayıyı gir\n"; // uyarı 10 std::cin >> tam1; // tamsayı oku 11 std::cout << İkinci tamsayıyı gir"; // uyarı 12 std::cin >> tam2; // tamsayı oku 13 toplam = tam1 + tam2; // toplama atama 14 std::cout << Toplam= " << toplam << std::endl; // yaz 15 16 return 0; // program sonu 17 } İlk tamsayıyı gir 45 İkinci tamsayıyı gir 72 Toplam= 117

15.4 C++ Standard Kütüphanesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 8 C++ programları Fonksiyonlar ve Sınıflar dan oluşur Çoğu programcı kütüphane fonksiyonları kullanır C++ öğrenmenin iki kısmı Dili öğren Kütüphane fonksiyonlarını öğren Kendi fonksiyonlarını yaratma Avantaj: nasıl çalıştığını biliyorsunuzdur Dezavantaj: zaman alıcı, etkinliğini korumak ve iyi dizayn etmek zordur

15.5 Header Dosyaları Header dosyaları Her standard kütüphane header dosyalarına sahiptir Fonksiyon prototipleri, veri tipi tanımlamaları, ve sabitler içerir.h ile bitenler eski-tip" header-lardır Okuyucu tanımlı header dosyaları Kendi header dosyanı oluştur.h uzantılı olsun Diğer dosyalarda kullanmak için o dosyaya #include dosyam.h" ekle Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 9

15.6 Satıriçi (Inline) Fonksiyonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 10 Çağrılan fonksiyonlar Derleme zamanını uzatır Fonksiyonun önündeki inline belirteci fonksiyonun o yere kopyalanmasını sağlar Çağrılan fonksiyon yerine o fonksiyonun bir kopyasını koyar Hızı artırır fakat dosya boyutunu büyültür Derleyici inline belirtecini gözardı edebilir En küçük fonksiyonlar hariç diğerlerini gözardı eder inline double kup( const double s ) {returns * s * s;} Using deyimleri using std::cout; yazarak programda std::cout yerine cout yazabiliriz std::cin ve std::endl için de uygulanabilir

15.6 Satıriçi (Inline) Fonksiyonları bool Boolean yeni veri tipi, ya true ya da false olur C++ Anahtar kelimeleri C ve C++ dillerindeki ortak anahtar kelimeler auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while Sadece C++ asm bool catch class const_cast delete dynamic_cast explicit false friend inline mutable namespace new operator private protected public reinterpret_cast static_cast template this throw true try typeid typename using virtual wchar_t Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 11

15.7 Referanslar ve Referans Parametreleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 12 Değer ile Çağırma Fonksiyona geçen verinin kopyası Kopyayı değiştirebilir fakat orjinali değil Referans ile Çağırma Fonksiyon veriye doğrudan erişim sağlayabilir Değişiklikler orjinali etkiler Argümentler için referans parametreleri & kullan void degistir(int &degisken) { degisken += 3; } Orjinal girdi değişkenine 3 ekler int y = &x y yi değiştirmekle x de değişir

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 13 15.7 Referanslar ve Referans Parametreleri Sallantı referansları Referansları değişkenlere atadığınızdan emin olunuz Eğer fonksiyon bir değişkene referans gönderirse, değişkenin static olduğundan emin olunuz Aksi halde, otomatik olup fonksiyon bittiğinde yok olur Çoklu referanslar Pointer gibi her referansda & gerekli int &a, &b, &c;

1 // Fig. 15.5: fig15_05.cpp 2 // Referanslarla 15.7 Referanslar ve Referans Parametreleri 3 // değer ile çagğırma ve referans ile çağırma karşılaştırılması 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 int degerilekare( int ); 10 void refilekare( int & ); 11 12 int main() 13 { 14 int x = 2, z = 4; 15 16 cout << "x = " << x << " degerilekare den önce\n" 17 << " degerilekare nin gönderdiği değer: " 18 << degerilekare( x ) << endl 19 << "x = " << x << " degerilekareden sonra\n" << endl; 20 21 cout << "z = " << z << " refilekare den önce " << endl; 22 refilekare( z ); 23 cout << "z = " << z << " refilekare den sonra " << endl; 24 25 return 0; 26 } 27 28 int degerilekare( int a ) 29 { 30 return a *= a; // çağırıcı argümenti değişmez 31 } C++ " Daha İyi Bir C " Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 14

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 15 15.7 Referanslar ve Referans Parametreleri 32 33 void refilekare( int &cref ) 34 { 35 cref *= cref; // çağirıcı argümenti değişti 36 } x = 2 degerilekare den önce degerilekare nin gönderdiği değer: 4 x = 2 degerilekare den sonra z = 4 refilekare den önce z = 16 refilekare den sonra

15.8 Default Argumentler ve Boş Parametre Listesi Fonksiyon parametresi yazılmaz ise, default değeri alır sabit, global değişken, veya fonksiyon çağrımı olabilir Yeterince parametre belirtilmemişse, en sağdakiler default larını alır Fonksiyon parametresinde default-ları kurma int fonksiyonum( int x = 1, int y = 2, int z = 3 ); Boş parametre listesi C de, boş parametre listesinin anlamı fonksiyonun herhangi bir argümenti almasıdır C++ ise fonksiyonun hiçbir argüment almamasıdır Fonksiyonun hiç bir parametre almayacağını deklare etmek için: Parantez içine void yaz veya boş bırak Prototipler: void fonk1( void ); void fonk2(); Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 16

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 17 1 // Fig. 15.8: fig15_08.cpp 2 // default argümentler kullanma 15.8 Default Argumentler ve Boş Parametre Listesi 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int kubhacim( int uzunluk= 1, int genislik= 1, int yukseklik= 1 ); 9 10 int main() 11 { 12 cout << "default küb hacmi: " << kuphacim() 13 << "\n\n uzunluğu 10, genişliği 1 ve yüksekliği 1 \n" 14 << olan kübün hacmi: " << kubhacim( 10 ) 15 << "\n\n uzunluğu 10, genişliği 5 ve yüksekliği 1 \n" 16 << olan kübün hacmi: " << kubhacim( 10, 5 ) 17 << "\n\n uzunluğu 10, genişliği 5 ve yüksekliği 2\n" 18 << olan kübün hacmi: " << kubhacim( 10, 5, 2 ) 19 << endl; 20 21 return 0; 22 } 23 24 // Hacmi hesapla 25 int kubhacim( int uzunluk, int genislik, int yukseklik ) 26 { 27 return uzunluk * genislik * yukseklik; 28 }

15.8 Default Argumentler ve Boş Parametre Listesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 18 default küb hacmi: 1 uzunluğu 10, genişliği 1 ve yüksekliği 1 olan kübün hacmi: 10 uzunluğu 10, genişliği 5 ve yüksekliği 1 olan kübün hacmi: 50 uzunluğu 10, genişliği 5 ve yüksekliği 2 olan kübün hacmi: 100

15.9 Tek Operandlı(Unary) Hedef Karar Operatörü Unary hedef karar operatörü (::) Yerel değişken aynı ada sahipse global değişkene erişim sağla degisken yerine ::degisken kullan static_cast<yenitip> (degisken) yenitip tipindeki degişken nin kopyasını oluşturur Int-leri float-lara, vs çevirir. Akış düzenleyicileri Çıktı formatını değiştirir setprecision float-lar için duyarlılığı kurar (default 6 rakam) setiosflags çıktıyı formatlar setwidth alan genişliğini kurar Bölüm 21-e bakınız Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 19

15.9 Tek Operandlı(Unary) Hedef Karar Operatörü 1 // Fig. 15.9: fig15_09.cpp 2 // tek operandlı hedef karar operatörü 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::ios; 8 9 #include <iomanip> 10 11 using std::setprecision; 12 using std::setiosflags; 13 using std::setw; 14 15 const double PI = 3.14159265358979; 16 17 int main() 18 { 19 const float PI = static_cast< float >( ::PI ); 20 21 cout << setprecision( 20 ) 22 << " PI nin yerel float değeri = " << PI 23 << "\n PI nin global double değeri = " << ::PI << endl; 24 25 cout << setw( 28 ) << PI nin yerel float değeri = " 26 << setiosflags( ios::fixed ios::showpoint ) 27 << setprecision( 10 ) << PI << endl; 28 return 0; 29 } Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 20

15.9 Tek Operandlı(Unary) Hedef Karar Operatörü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 21 PI nin yerel float değeri = 3.141592741012573242 PI nin global double değeri = 3.141592653589790007 PI nin yerel float değeri = = 3.1415927410

15.10 Fonksiyon Yüklemeleri Fonksiyon yüklemeleri: Aynı adlı farklı parametreli fonksiyonlar Yüklenmiş fonksiyonlar benzer görevleri yapmalıdırlar Tamsayıların karesini alan veya reel sayıların karesini alan fonksiyonlar gibi int kare( int x) {return x * x;} float square(float x) { return x * x; } Program fonksiyonu imzası ile çağırır İmza, fonksiyon adı ve parametre tipi ile belirlenir Tip emniyetli bağlantı uygun yüklenmiş fonksiyonu çağırmayı garanti eder Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 22

15.10 Fonksiyon Yüklemeleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 23 1 // Fig. 15.10: fig15_10.cpp 2 // Yüklenmiş fonksiyon kullanımı 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int kare( int x ) { return x * x; } 9 10 double kare( double y ) { return y * y; } 11 12 int main() 13 { 14 cout << 7 tamsayısının karesi " << kare( 7 ) 15 << "\n 7.5 reel (double)sayısının karesi " << kare( 7.5 ) 16 << endl; 17 18 return 0; 19 } 7 tamsayısının karesi 49 7.5 reel (double)sayısının karesi 56.25

15.11 Fonksiyon Şablonları Fonksiyon Şablonları Yüklenmiş fonksiyonlar oluşturmanın kompakt yolu Anahtar kelime template Her formal tip parametreden önce anahtar kelime class veya tipadı template < class T > // veya template< tipadı T > T kare( T deger1) { return deger1 * deger1; } T çağrılan fonksiyondaki tip parametresi ile yer değiştirecek int x; int y = kare(x); Eğer int parametre ise, tüm T ler int olur float, double, long... kullanılabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 24

1 // Fig. 15.11: fig15_11.cpp 2 // fonksiyon şablonu kullanımı 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 template < class T > 10 T maximum( T deger1, T deger2, T deger3 ) 11 { 12 T max = deger1; 13 14 if ( deger2 > max ) 15 max = deger2; 16 17 if ( deger3 > max ) 18 max = deger3; 19 20 return max; 21 } 22 23 int main() 24 { 25 int int1, int2, int3; 26 27 cout << Üç tamsayı gir: "; 28 cin >> int1 >> int2 >> int3; 29 cout << maksimum: " 15.11 Fonksiyon Şablonları 30 << maximum( int1, int2, int3 ); // int versiyon C++ " Daha İyi Bir C " Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 25

15.11 Fonksiyon Şablonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 26 31 32 double double1, double2, double3; 33 34 cout << "\n Üç double değer gir: "; 35 cin >> double1 >> double2 >> double3; 36 cout << maksimum: " 37 << maximum( double1, double2, double3 ); // double versiyonu 38 39 char char1, char2, char3; 40 41 cout << "\n Üç karakter gir: "; 42 cin >> char1 >> char2 >> char3; 43 cout << maksimumn: " 44 << maximum( char1, char2, char3 ) // char versiyonu 45 << endl; 46 47 return 0; 48 } Üç tamsayı gir: 1 2 3 maksimum: 3 Üç double sayı gir : 3.3 2.2 1.1 maksimum: 3.3 Üç karakter gir: A C B maksimum: C

Bölüm 15 - C++ " Daha İyi Bir C " Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 1 İçerik 15.1 Giriş 15.2 C++ 15.3 Bir Basit Program: İki Tamsayıyı Toplama 15.4 C++ Standard Kütüphanesi 15.5 Header Dosyaları 15.6 Satıriçi (Inline) Fonksiyonları 15.7 Referanslar ve Referans Parametreleri 15.8 Default Argumentler ve Boş Parametre Listesi 15.9 Tek Operandlı(Unary) Hedef Karar Operatörü 15.10 Fonksiyon Yüklemeleri 15.11 Fonksiyon Şablonları

15.1 Giriş Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 2 İlk 14 bölüm Yordamsal programlama C ile yukarıdan-aşağı programlama dizaynı Bölüm 15-23 C++ Nesne tabanlı programlama (sınıflar, nesneler, gruplama) Nesne tabanlı programlama (kalıt, polimorfism) Genel programlama (sınıf (class) ve fonksiyon şablonları)

15.2 C++ C++ Bir çok C özelliğini geliştirdi Nesne tabanlı kapasiteye sahip Yazılım kalitesini ve tekrar kullanılabilirliğini artırır Bell Labs de Bjarne Stroustrup geliştirdi "sınıflı C " olarak adlandırılır C++ (artırma operatörü) - C nin gelişmiş sürümü C den çok üstün C++ derleyicisi C programlarını da derleyebilir C programlarını adım adım C++ a genişletir ANSI C++ Son sürümü http://www.ansi.org/ http://www.cygnus.com/misc/wp/ de bedava Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 3

15.3 Bir Basit Program: İki Tamsayıyı Toplama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 4 Dosya uzantısı C dosyası:.c C++ dosyası:.cpp (kullandığımız),.cxx,.c (büyük harf) Farkları C++ da " açıklamlar için" // kullan Örneğin: // açıklama yazısı <iostream> - girdi çıktı (input/output) akışı header dosyası Gönderme tipleri tüm fonksiyonlar gönderme tipini belirtmelidir C de gerek yok, fakat C++ da gerekli C++ değişkenler hemen hemen her yerde deklare edilebilir C de herhangi bir işletilebilir deyimden önce blok olarak verilir

15.3 Bir Basit Program: İki Tamsayıyı Toplama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 5 C++ da Input/Output Karakter akışları(streams) ile gerçeklenir Akışlar input/output nesnesine gönderilir Output std::cout - standard çıktı akışı (ekrana bağlanır) << stream ekleme operatörü std::cout << merhaba"; merhaba" kelimesini std::cout a ekler yani yazar Input std::cin - standard input nesnesi (klavyeye bağlanır) >> stream alma operatörü std::cin >> değişken; Klavyeden akışı alır ve değişken e aktarır

15.3 Bir Basit Program: İki Tamsayıyı Toplama std::endl satır sonu" Akış düzenleyici yeni satır yazar ve çıktı desteğini temizler Bazı sistemler yazılacak yeterli tekst olana kadar çıktıyı görüntülemez std::endl tekstin görünmesini sağlar using deyimleri std:: önek in kaldırılmasına izin verir Sonra tartışılacak Taşırma Çoklu << veya >> operatörleri tek bir deyimde std::cout << Merhaba " << sınıf" << std::endl; Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 6

15.3 Bir Basit Program: İki Tamsayıyı Toplama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 7 1 // Fig. 15.1: fig15_01.cpp 2 // Toplama programı 3 #include <iostream> 4 5 int main() 6 { 7 int tam1, tam2, toplam; // deklarasyon 8 9 std::cout << İlk tamsayıyı gir\n"; // uyarı 10 std::cin >> tam1; // tamsayı oku 11 std::cout << İkinci tamsayıyı gir"; // uyarı 12 std::cin >> tam2; // tamsayı oku 13 toplam = tam1 + tam2; // toplama atama 14 std::cout << Toplam= " << toplam << std::endl; // yaz 15 16 return 0; // program sonu 17 } İlk tamsayıyı gir 45 İkinci tamsayıyı gir 72 Toplam= 117

15.4 C++ Standard Kütüphanesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 8 C++ programları Fonksiyonlar ve Sınıflar dan oluşur Çoğu programcı kütüphane fonksiyonları kullanır C++ öğrenmenin iki kısmı Dili öğren Kütüphane fonksiyonlarını öğren Kendi fonksiyonlarını yaratma Avantaj: nasıl çalıştığını biliyorsunuzdur Dezavantaj: zaman alıcı, etkinliğini korumak ve iyi dizayn etmek zordur

15.5 Header Dosyaları Header dosyaları Her standard kütüphane header dosyalarına sahiptir Fonksiyon prototipleri, veri tipi tanımlamaları, ve sabitler içerir.h ile bitenler eski-tip" header-lardır Okuyucu tanımlı header dosyaları Kendi header dosyanı oluştur.h uzantılı olsun Diğer dosyalarda kullanmak için o dosyaya #include dosyam.h" ekle Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 9

15.6 Satıriçi (Inline) Fonksiyonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 10 Çağrılan fonksiyonlar Derleme zamanını uzatır Fonksiyonun önündeki inline belirteci fonksiyonun o yere kopyalanmasını sağlar Çağrılan fonksiyon yerine o fonksiyonun bir kopyasını koyar Hızı artırır fakat dosya boyutunu büyültür Derleyici inline belirtecini gözardı edebilir En küçük fonksiyonlar hariç diğerlerini gözardı eder inline double kup( const double s ) {returns * s * s;} Using deyimleri using std::cout; yazarak programda std::cout yerine cout yazabiliriz std::cin ve std::endl için de uygulanabilir

15.6 Satıriçi (Inline) Fonksiyonları bool Boolean yeni veri tipi, ya true ya da false olur C++ Anahtar kelimeleri C ve C++ dillerindeki ortak anahtar kelimeler auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while Sadece C++ asm bool catch class const_cast delete dynamic_cast explicit false friend inline mutable namespace new operator private protected public reinterpret_cast static_cast template this throw true try typeid typename using virtual wchar_t Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 11

15.7 Referanslar ve Referans Parametreleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 12 Değer ile Çağırma Fonksiyona geçen verinin kopyası Kopyayı değiştirebilir fakat orjinali değil Referans ile Çağırma Fonksiyon veriye doğrudan erişim sağlayabilir Değişiklikler orjinali etkiler Argümentler için referans parametreleri & kullan void degistir(int &degisken) { degisken += 3; } Orjinal girdi değişkenine 3 ekler int y = &x y yi değiştirmekle x de değişir

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 13 15.7 Referanslar ve Referans Parametreleri Sallantı referansları Referansları değişkenlere atadığınızdan emin olunuz Eğer fonksiyon bir değişkene referans gönderirse, değişkenin static olduğundan emin olunuz Aksi halde, otomatik olup fonksiyon bittiğinde yok olur Çoklu referanslar Pointer gibi her referansda & gerekli int &a, &b, &c;

1 // Fig. 15.5: fig15_05.cpp 2 // Referanslarla 15.7 Referanslar ve Referans Parametreleri 3 // değer ile çagğırma ve referans ile çağırma karşılaştırılması 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 int degerilekare( int ); 10 void refilekare( int & ); 11 12 int main() 13 { 14 int x = 2, z = 4; 15 16 cout << "x = " << x << " degerilekare den önce\n" 17 << " degerilekare nin gönderdiği değer: " 18 << degerilekare( x ) << endl 19 << "x = " << x << " degerilekareden sonra\n" << endl; 20 21 cout << "z = " << z << " refilekare den önce " << endl; 22 refilekare( z ); 23 cout << "z = " << z << " refilekare den sonra " << endl; 24 25 return 0; 26 } 27 28 int degerilekare( int a ) 29 { 30 return a *= a; // çağırıcı argümenti değişmez 31 } C++ " Daha İyi Bir C " Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 14

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 15 15.7 Referanslar ve Referans Parametreleri 32 33 void refilekare( int &cref ) 34 { 35 cref *= cref; // çağirıcı argümenti değişti 36 } x = 2 degerilekare den önce degerilekare nin gönderdiği değer: 4 x = 2 degerilekare den sonra z = 4 refilekare den önce z = 16 refilekare den sonra

15.8 Default Argumentler ve Boş Parametre Listesi Fonksiyon parametresi yazılmaz ise, default değeri alır sabit, global değişken, veya fonksiyon çağrımı olabilir Yeterince parametre belirtilmemişse, en sağdakiler default larını alır Fonksiyon parametresinde default-ları kurma int fonksiyonum( int x = 1, int y = 2, int z = 3 ); Boş parametre listesi C de, boş parametre listesinin anlamı fonksiyonun herhangi bir argümenti almasıdır C++ ise fonksiyonun hiçbir argüment almamasıdır Fonksiyonun hiç bir parametre almayacağını deklare etmek için: Parantez içine void yaz veya boş bırak Prototipler: void fonk1( void ); void fonk2(); Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 16

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 17 1 // Fig. 15.8: fig15_08.cpp 2 // default argümentler kullanma 15.8 Default Argumentler ve Boş Parametre Listesi 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int kubhacim( int uzunluk= 1, int genislik= 1, int yukseklik= 1 ); 9 10 int main() 11 { 12 cout << "default küb hacmi: " << kuphacim() 13 << "\n\n uzunluğu 10, genişliği 1 ve yüksekliği 1 \n" 14 << olan kübün hacmi: " << kubhacim( 10 ) 15 << "\n\n uzunluğu 10, genişliği 5 ve yüksekliği 1 \n" 16 << olan kübün hacmi: " << kubhacim( 10, 5 ) 17 << "\n\n uzunluğu 10, genişliği 5 ve yüksekliği 2\n" 18 << olan kübün hacmi: " << kubhacim( 10, 5, 2 ) 19 << endl; 20 21 return 0; 22 } 23 24 // Hacmi hesapla 25 int kubhacim( int uzunluk, int genislik, int yukseklik ) 26 { 27 return uzunluk * genislik * yukseklik; 28 }

15.8 Default Argumentler ve Boş Parametre Listesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 18 default küb hacmi: 1 uzunluğu 10, genişliği 1 ve yüksekliği 1 olan kübün hacmi: 10 uzunluğu 10, genişliği 5 ve yüksekliği 1 olan kübün hacmi: 50 uzunluğu 10, genişliği 5 ve yüksekliği 2 olan kübün hacmi: 100

15.9 Tek Operandlı(Unary) Hedef Karar Operatörü Unary hedef karar operatörü (::) Yerel değişken aynı ada sahipse global değişkene erişim sağla degisken yerine ::degisken kullan static_cast<yenitip> (degisken) yenitip tipindeki degişken nin kopyasını oluşturur Int-leri float-lara, vs çevirir. Akış düzenleyicileri Çıktı formatını değiştirir setprecision float-lar için duyarlılığı kurar (default 6 rakam) setiosflags çıktıyı formatlar setwidth alan genişliğini kurar Bölüm 21-e bakınız Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 19

15.9 Tek Operandlı(Unary) Hedef Karar Operatörü 1 // Fig. 15.9: fig15_09.cpp 2 // tek operandlı hedef karar operatörü 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::ios; 8 9 #include <iomanip> 10 11 using std::setprecision; 12 using std::setiosflags; 13 using std::setw; 14 15 const double PI = 3.14159265358979; 16 17 int main() 18 { 19 const float PI = static_cast< float >( ::PI ); 20 21 cout << setprecision( 20 ) 22 << " PI nin yerel float değeri = " << PI 23 << "\n PI nin global double değeri = " << ::PI << endl; 24 25 cout << setw( 28 ) << PI nin yerel float değeri = " 26 << setiosflags( ios::fixed ios::showpoint ) 27 << setprecision( 10 ) << PI << endl; 28 return 0; 29 } Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 20

15.9 Tek Operandlı(Unary) Hedef Karar Operatörü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 21 PI nin yerel float değeri = 3.141592741012573242 PI nin global double değeri = 3.141592653589790007 PI nin yerel float değeri = = 3.1415927410

15.10 Fonksiyon Yüklemeleri Fonksiyon yüklemeleri: Aynı adlı farklı parametreli fonksiyonlar Yüklenmiş fonksiyonlar benzer görevleri yapmalıdırlar Tamsayıların karesini alan veya reel sayıların karesini alan fonksiyonlar gibi int kare( int x) {return x * x;} float square(float x) { return x * x; } Program fonksiyonu imzası ile çağırır İmza, fonksiyon adı ve parametre tipi ile belirlenir Tip emniyetli bağlantı uygun yüklenmiş fonksiyonu çağırmayı garanti eder Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 22

15.10 Fonksiyon Yüklemeleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 23 1 // Fig. 15.10: fig15_10.cpp 2 // Yüklenmiş fonksiyon kullanımı 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int kare( int x ) { return x * x; } 9 10 double kare( double y ) { return y * y; } 11 12 int main() 13 { 14 cout << 7 tamsayısının karesi " << kare( 7 ) 15 << "\n 7.5 reel (double)sayısının karesi " << kare( 7.5 ) 16 << endl; 17 18 return 0; 19 } 7 tamsayısının karesi 49 7.5 reel (double)sayısının karesi 56.25

15.11 Fonksiyon Şablonları Fonksiyon Şablonları Yüklenmiş fonksiyonlar oluşturmanın kompakt yolu Anahtar kelime template Her formal tip parametreden önce anahtar kelime class veya tipadı template < class T > // veya template< tipadı T > T kare( T deger1) { return deger1 * deger1; } T çağrılan fonksiyondaki tip parametresi ile yer değiştirecek int x; int y = kare(x); Eğer int parametre ise, tüm T ler int olur float, double, long... kullanılabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 24

1 // Fig. 15.11: fig15_11.cpp 2 // fonksiyon şablonu kullanımı 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 template < class T > 10 T maximum( T deger1, T deger2, T deger3 ) 11 { 12 T max = deger1; 13 14 if ( deger2 > max ) 15 max = deger2; 16 17 if ( deger3 > max ) 18 max = deger3; 19 20 return max; 21 } 22 23 int main() 24 { 25 int int1, int2, int3; 26 27 cout << Üç tamsayı gir: "; 28 cin >> int1 >> int2 >> int3; 29 cout << maksimum: " 15.11 Fonksiyon Şablonları 30 << maximum( int1, int2, int3 ); // int versiyon C++ " Daha İyi Bir C " Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 25

15.11 Fonksiyon Şablonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ " Daha İyi Bir C " 26 31 32 double double1, double2, double3; 33 34 cout << "\n Üç double değer gir: "; 35 cin >> double1 >> double2 >> double3; 36 cout << maksimum: " 37 << maximum( double1, double2, double3 ); // double versiyonu 38 39 char char1, char2, char3; 40 41 cout << "\n Üç karakter gir: "; 42 cin >> char1 >> char2 >> char3; 43 cout << maksimumn: " 44 << maximum( char1, char2, char3 ) // char versiyonu 45 << endl; 46 47 return 0; 48 } Üç tamsayı gir: 1 2 3 maksimum: 3 Üç double sayı gir : 3.3 2.2 1.1 maksimum: 3.3 Üç karakter gir: A C B maksimum: C

Bölüm 16 - Sınıflar (Class) ve Veri Soyutlaması Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 1 Ġçerik 16.1 Giriş 16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama 16.3 Class Alanı ve Class Üyelerine Erişim 16.4 Bütünlemeden Arayüzü Ayırma 16.5 Üyelere Erişim Kontrolü 16.6 Erişim ve Yarar Fonksiyonları 16.7 Class Nesnelerini Belirleme: Oluşturucular (Constructors) 16.8 Oluşturucularla Default Argümentlerin Kullanımı 16.9 Yokedicilerin (Destructors) Kullanımı 16.10 Oluşturucular ve Yokediciler Çağrıldığında 16.11 Veri Üyelerini ve Üye Fonksiyonlarını Kullanma 16.12 Bir Ġnce Tuzak: Özel (private) bir Veri Üyesine bir Referans Gönderme 16.13 Default Üyebazlı Kopyayla Atama 16.14 Yazılım Kullanılabilirliği

16.1 Giriş Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 2 Nesne -Tabanlı programlama (OOP) Verileri (nesne) ve fonksiyonları (davranış) class adı verilen paketlere yükleme Veri ve fonksiyonlar yakın ilişkiye sahiptir Bilgi gizleme Uygulama detayları class-ların içinde gizlidir C++ programlama birimi: class class bir mavi kopya (plan) gibidir tekrar kullanılabilirdir Nesneler class-lardan oluşturulur Örneğin, bir ev mavi kopya class dan oluşturulur C programcıları fonksiyonlara konsantre olurlar

16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 3 Class Niteliklere (veri üyeleri) ve davranışlara (üye fonksiyonları) sahip olan model nesneleri class anahtar kelimesi ile tanımlanır 1 class Zaman { 2 public: 3 Zaman(); 4 void kurzaman( int, int, int ); 5 void yazaskeri(); 6 void yazstandard(); 7 private: 8 int saat; // 0-23 9 int dakika; // 0-59 10 int saniye; // 0-59 11 }; Public: ve Private: üye erişim belirteçleridir kurzaman, yazaskeri, ve yazstandard üye fonksiyonlardır. Zaman oluşturucudur. saat, dakika, ve saniye veri üyeleridir.

16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 4 Format Gövde küme parantezleri ({ ve }) içinde yazılır Class tanımı noktalıvirgül ile biter Üye fonksiyonlar ve veriler Public - Programın Zaman class nesnesine her erişitiğinde erişilebilirdir Private sadece class-ın üye fonksiyonlarına erişilebilirdir Protected sonra tartışılacak

16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 5 Oluşturucu Bir class nesnesinin veri üyelerini belirten özel üye fonksiyondur Değer göndermez class ile aynı ada sahiptir Deklarasyonlar class tanımlandıktan sonra bir veri tipi olarak kullanılabilirdir Zaman aksam, zamandizisi[ 5 ], *zamanapointer, &yemekzamanı= aksam; Not: class adı yeni tip bir belirteç oldu. // Zaman tipi nesne // Zaman nesnesinin dizisi // nesneye pointer // bir Zaman nesnesine referans

16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 6 Binary hedef karar operatörü (::) Üye fonksiyona hangi class-ın sahip olduğunu belirtir Farklı class-ların üye fonksiyonlar aynı ada sahip olabilir Tanım class-ı üye fonksiyonları için format Return_Tipi ClassAdı::ÜyeFonksiyonAdı( ){ }

16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama Eğer üye fonksiyon class-ın içinde tanımlanmış ise Hedef karar operatörü ve class adına gerek yoktur Bir fonksiyonu class dışında tanımlamak public veya private olmasını değiştirmez Class-lar yazılımın tekrar kullanımını teşvik eder Kalıtsallık özelliği yeni class-ların eskilerinden üretilmesine izin verir Aşağıdaki programda Zaman oluşturucusu veri üyelerini sıfırlar Oluşum aşamasında nesnenin kararlı konumda olmasına emin olunuz Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 7

1 // Fig. 16.2: fig16_02.cpp 2 // Zaman class-ı. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 // zaman soyut veri tipi tanımı 9 class Zaman { 10 public: 11 Zaman(); // oluşturucu 12 void kurzaman( int, int, int ); // saat dakika ve saniyeyi kur 13 void yazaskeri(); // askeri zaman formatında yaz 14 void yazstandard(); // standard zaman formatında yaz 15 private: 16 int saat; // 0 23 17 int dakika; // 0 59 18 int saniye; // 0 59 19 }; 20 21 // Zaman oluşturucu her bir veri üyesini sıfır alır. 22 // tüm Zaman nesnelerinin kararlı durumda olduğuna garantile. 23 Zaman::Zaman() { saat = dakika = saniye = 0; } 24 25 // Askeri zamanı kullanarak yeni bir zaman değeri gir. Ğeçerliliğini kontrol et 26 // Geçersiz değerleri sıfır yap 27 void Zaman::kurZaman( int s, int d, int sn ) 28 { 29 saat = ( s >= 0 && s < 24 )? s : 0; 30 dakika = ( d >= 0 && d < 60 )? d : 0; 31 saniye= ( sn >= 0 && sn < 60 )? sn : 0; 32 } SINIFLAR VE VERİ SOYUTLAMASI 16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 8

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 9 33 34 // Askeri formatta zamanı taz 16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama 35 void Zaman::yazAskeri() 36 { 37 cout << ( saat < 10? "0" : "" ) << saat << ":" 38 << ( dakika < 10? "0" : "" ) << dakika; 39 } 40 41 // Standart formatta zamanı yaz 42 void Zaman::yazStandard() 43 { 44 cout << ( ( saat == 0 saat == 12 )? 12 : saat % 12 ) 45 << ":" << ( dakika < 10? "0" : "" ) << dakika 46 << ":" << ( saniye < 10? "0" : "" ) << saniye 47 << ( saat < 12? " AM" : " PM" ); 48 } 49 50 // Test et 51 int main() 52 { 53 Zaman t; // Zaman sınıfının t nesnesini belirle 54 55 cout << Ġlk askeri zaman: "; 56 t.yazaskeri(); 57 cout << "\n Ġlk standart zaman: "; 58 t.yazstandard(); 59

16.2 Bir Zaman Soyut Veri Tipini bir Class ile Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 10 60 t.kurzaman( 13, 27, 6 ); 61 cout << "\n\n kurzaman dan sonra askeri zaman: "; 62 t.yazaskeri(); 63 cout << "\n kurzaman dan sonra standart zaman: "; 64 t.yazstandard(); 65 66 t.kurzaman( 99, 99, 99 ); // yanlış girdi dene 67 cout << "\n\n Yanlış girdiden sonra:" 68 << "\naskeri zaman: "; 69 t.yazaskeri(); 70 cout << "\nstandart zaman: "; 71 t.yazstandard(); 72 cout << endl; 73 return 0; 74 } Ġlk askeri zaman: 00:00 Ġlk standart zaman: 12:00:00 AM KurZaman dan sonra askeri zaman: 13:27 KurZaman dan sonra standart zaman: 1:27:06 PM Yanlış girdiden sonra: Askeri zaman: 00:00 Standard zaman: 12:00:00 AM

16.3 Class Alanı(Hedefi) ve Class Üyelerine Erişim Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 11 Class alanı Veri üyeleri ve Veri Fonksiyonlarına Erişim Dosya Alanı Üye olmayan fonksiyonlar Fonksiyon Alanı Üye fonksiyonlarda tanımlanan değişkenler, fonksiyon işi bitince yokedilirler Alan İçi Tüm üye fonksiyonlarca erişilebilinen üyeler İsim ile refere edilirler

16.3 Class Alanı(Hedefi) ve Class Üyelerine Erişim Alan dışı Bir kulp kullan Bir nesne adı, nesneye pointer veya nesneye referans Class üyelerine erişim struct daki gibidir Nesneler için nokta (.) veya pointer-lar için ok (->) Örnek: t.saat, t nin saat elemanıdır zamanptr->saat saat elemanıdır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 12

1 // Fig. 16.3: fig16_03.cpp 16.3 Class Alanı(Hedefi) ve Class Üyelerine Erişim 2 // class üyesine erişim operatörleri. ve -> kullanımı 3 // 4 // UYARI: BUNDAN SONRAKĠ ÖRNEKLERDE KULLANICI VERĠSĠ YOK! 5 #include <iostream> 6 7 using std::cout; 8 using std::endl; 9 10 // basit class Sayac 11 class Sayac { 12 public: 13 int x; 14 void yaz() { cout << x << endl; } 15 }; 16 17 int main() 18 { 19 Sayac sayac, // sayac nesnesi oluştur 20 *sayacptr = &sayac, // sayaca pointer 21 &sayacref = sayac; // sayaca referans 22 23 cout << x e 7 ata ve nesne adını kullanarak yaz: "; 24 sayac.x = 7; // veri üyesi x e 7 ata 25 sayac.yaz(); // yaz üye fonksiyonunu çağır 26 27 cout << x e 8 ata ve referans kullanarak yaz: "; 28 sayacref.x = 8; // veri üyesi x e 8 ata 29 sayacref.yaz(); // call member function print 30 SINIFLAR VE VERİ SOYUTLAMASI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 13

16.3 Class Alanı(Hedefi) ve Class Üyelerine Erişim Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 14 31 cout << x e 10 ata ve pointer kullanarak yaz: "; 32 sayacptr->x = 10; // veri üyesi x e 10 ata 33 sayacptr->yaz(); // yaz üye fonksiyonunu çağır 34 return 0; 35 } x e 7 ata ve nesne adı kullanarak yaz: 7 x e 8 ata ve referans kullanarak yaz: : 8 x e 10 ata ve pointer kullanarak yaz: 10

16.4 Bütünlemeden Arayüzü Ayırma Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 15 Bütünlemeden arayüzü ayırma Program düzenlemelerini kolaylaştırır C++ programları iki parçaya ayrılabilir: Header dosyaları class tanımları ve fonksiyon prototipleri içerir Kaynak-kod dosyaları üye fonksiyon tanımlarını içerir Program taslağı: Önceki Zaman sınıfını kullanarak, header dosyası oluştur Bir kaynak kod dosyası oluştur Sınıf tanımlarını elde etmek için header dosyasını yükle Sınıfın üye fonksiyonlarını tanımla

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 16 1 // Fig. 16.4: zaman1.h 2 // Zaman sınıfının deklarasyonu. 16.4 Bütünlemeden Arayüzü Ayırma 3 // üye fonksiyonlar zaman1.cpp de tanımlandı 4 5 // header dosyasının çoklu kullanılmasını engelle 6 #ifndef ZAMAN1_H 7 #define ZAMAN1_H 8 9 // soyut veri tipi tanımı Zaman 10 class Zaman { 11 public: 12 Zaman(); // constructor 13 void kurzaman( int, int, int ); // saat, dakika saniyeyi kur 14 void yazaskeri(); // askeri formatta yaz 15 void yazstandard(); // standart formatta yaz 16 private: 17 int saat; // 0-23 18 int dakika; // 0-59 19 int saniye; // 0-59 20 }; 21 22 #endif

23 // Fig. 16.4: zaman1.cpp 24 // Zaman sınıfı için üye fonksiyonların tanımı. 16.4 Bütünlemeden Arayüzü Ayırma 25 #include <iostream> 26 27 using std::cout; 28 29 #include zaman1.h" 30 31 // Zaman oluşturucusu her bir veri üyesini sıfırlar. 32 // Tüm Zaman üyelerinin uygun değerlerle başlamasını garantile. 33 Zaman::Zaman() { saat = dakika = saniye = 0; } 34 35 // Askeri zaman kullanarak yeni bir Zaman değeri kur. Veri üyelerinin 36 // geçerliliğini test et. Geçersiz değerleri sıfırla. 37 void Zaman::kurZaman( int s, int d, int sn ) 38 { 39 saat = ( s >= 0 && s < 24 )? s : 0; 40 dakika = ( d >= 0 && d < 60 )? d : 0; 41 saniye = ( sn >= 0 && sn < 60 )? sn : 0; 42 } 43 44 // Askeri formatta zamanı yaz 45 void Zaman::yazAskeri() 46 { 47 cout << ( saat < 10? "0" : "" ) << saat << ":" 48 << ( dakika < 10? "0" : "" ) << dakika; 49 } SINIFLAR VE VERİ SOYUTLAMASI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 17

16.4 Bütünlemeden Arayüzü Ayırma Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 18 50 51 // Standart formatta zamanı yaz 52 void Zaman::yazStandard() 53 { 54 cout << ( ( saat == 0 saat == 12 )? 12 : saat % 12 ) 55 << ":" << ( dakika < 10? "0" : "" ) << dakika 56 << ":" << ( saniye < 10? "0" : "" ) << saniye 57 << ( saat < 12? " AM" : " PM" ); 58 }

59 // Fig. 16.4: fig16_04.cpp 60 // Zaman1 sınıfı için sürücü 61 // NOT: zaman1.cpp ile birlikte derle 62 #include <iostream> 63 64 using std::cout; 65 using std::endl; 66 67 #include zaman1.h" 68 69 // basit Zaman sınıfı testi için sürücü 70 int main() 71 { 72 Zaman t; // zaman sınıfı t nesnesini sabitle 73 74 cout << Ġlk askeri zaman: "; 75 t.yazaskeri(); 76 cout << "\n Ġlk standart zaman:"; 77 t.yazstandard(); 78 79 t.kurzaman( 13, 27, 6 ); 80 cout << "\n\n kurzaman dan sonra askeri zaman:"; 81 t.yazaskeri(); 82 cout << "\n kurzamandan sonra standard zaman:"; 83 t.yazstandard(); 84 16.4 Bütünlemeden Arayüzü Ayırma SINIFLAR VE VERİ SOYUTLAMASI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 19

16.4 Bütünlemeden Arayüzü Ayırma Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 20 85 t.kurzaman( 99, 99, 99 ); // hatalı veri girişi dene 86 cout << "\n\n Yanlış girdiden sonra:\n" 87 << Askeri zaman: "; 88 t.yazaskeri(); 89 cout << "\nstandard zaman: "; 90 t.yazstandard(); 91 cout << endl; 92 return 0; 93 } Ġlk askeri zaman: 00:00 Ġlk standart zaman: 12:00:00 AM kurzamandan sonra askeri zaman: 13:27 kurzamandan sonra standart zaman: 1:27:06 PM Yanlış girdiden sonra: Askeri zaman: 00:00 Standard Zaman: 12:00:00 AM

16.5 Üyelere Erişim Kontrolü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 21 public in amacı Kullanıcıya sınıfın sağladığı servisleri gösterir (arayüz) private ın amacı Default kurulum Sınıfın görevleri nasıl yaptığının detaylarını gizler (bütünleme) Private üyelere sadece public üye fonksiyonlar kullanılarak public arayüzü ile ulaşılabilir

1 // Fig. 16.5: fig16_05.cpp 2 // Özel sınıf üyelerine erişimi denemede 3 // ortaya çıkan hata. 4 #include <iostream> 5 6 using std::cout; 7 8 #include zaman1.h" 9 10 int main() 11 { 12 Zaman t; 13 14 // Hata: Zaman::saat' e erişilemez 15 t.saat = 7; 16 17 // Hata: Zaman::dakika' ya erişilemez 18 cout << dakika = " << t.dakika; 19 20 return 0; 21 } 16.5 Üyelere Erişim Kontrolü Compiling... Fig06_06.cpp D:\Fig06_06.cpp(15) : error C2248: saat' : cannot access private member declared in class Zaman' D:\Fig6_06\zaman1.h(18) : see declaration of saat' D:\Fig06_06.cpp(18) : error C2248: dakika' : cannot access private member declared in class Zaman' D:\zaman1.h(19) : see declaration of dakika' Error executing cl.exe. test.exe - 2 error(s), 0 warning(s) SINIFLAR VE VERİ SOYUTLAMASI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 22

16.6 Erişim ve Yarar Fonksiyonları Yarar (Utility) fonksiyonları Public fonksiyonların operasyonlarını destekleyen private fonksiyonlardır Kullanıcı tarafından doğrudan kullanıma yönelik değildir Erişim fonksiyonları Veri okuyup/görüntüleyen veya koşulları kontrol eden public fonksiyonlardır Bir içerici için, isempty fonksiyonunu çağırabilir Örnek Aylık satışları alan ve toplamı veren bir program Sadece erişim fonksiyonları gösteriliyor Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 23

16.6 Erişim ve Yarar Fonksiyonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 24 87 // Fig. 16.6: fig16_06.cpp 88 // bir yarar fonksiyonu kullanımı 89 // satisele.cpp ile kullan 90 #include satisele.h" 91 92 int main() 93 { 94 SatisEleman s; // bir s SatisEleman nesnesi oluştur 95 96 s.kullansatisformal(); // basit dizisel kod 97 s.yazyilliksatis(); // main de kontrol yapısı yok 98 return 0; 99 } 1. ay için satış miktarını gir: 5314.76 2. ay için satış miktarını gir: 4292.38 3. ay için satış miktarını gir: 4589.83 4. ay için satış miktarını gir: 5534.03 5. ay için satış miktarını gir: 4376.34 6. ay için satış miktarını gir: 5698.45 7. ay için satış miktarını gir: 4439.22 8. ay için satış miktarını gir: 5893.57 9. ay için satış miktarını gir: 4909.67 10. ay için satış miktarını gir: 5123.45 11. ay için satış miktarını gir: 4024.97 12. ay için satış miktarını gir: 5923.92 Toplam yıllık satış: $60120.59

16.7 Class Nesnelerini Belirleme: Oluşturucular (Constructors) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 25 Constructor fonksiyonları Sınıf üyelerine ilk atamaları yapabilir Sınıf ile aynı ada sahiptir, return tipi yoktur Üye fonkisyonların ilk değerleri constructor ile atanabilir veya sonradan verilebilir Nesnelerin deklarasyonu İlk değerler sağlanabilir İlk değerler sınıf oluşturucusuna argüment olarak geçer

16.7 Class Nesnelerini Belirleme: Oluşturucular (Constructors) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 26 Format Tip NesneAdı( değer1, değer2, ); Constructor üye değişkenlerine değer1, değer2, vs. atamalarını yapar Yeterince değer belirtilmemişse, en sağdaki değerler (programcının belirlediği) default değer alır Sınıfım Nesnem( 3, 4.0 );

16.8 Oluşturucularla Default Argümentlerin Kullanımı Default constructor Her sınıf için bir tane Argümentsiz olabilir default argumentlere sahiptir Default argumentler Default constructor fonksiyon prototipinde belirtilir (class tanımında) Sınıf dışındaki fonksiyon tanımında default değerler yazılmaz Örnek: ÖrnekSınıf( int = 0, float = 0); Constructor, sınıf ile aynı ada sahiptir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 27

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 28 1 // Fig. 16.7: zaman2.h 2 // Zaman sınıfı deklarasyonu. 16.8 Oluşturucularla Default Argümentlerin Kullanımı 3 // Üye fonksiyonlar zaman2.cpp de 4 5 // önişlemci komutları 6 // header dosyasının çoklu kullanımını engeller 7 #ifndef ZAMAN2_H 8 #define ZAMAN2_H 9 10 // Zaman soyut veri tipi deklarasyonu 11 class Zaman { 12 public: 13 Zaman( int = 0, int = 0, int = 0 ); // default constructor 14 void kurzaman( int, int, int ); // saat, dakika ve saniyeyi kur 15 void yazaskeri(); // Askeri formatta yazar 16 void yazstandard(); // Standard formatta yazar 17 private: 18 int saat; // 0-23 19 int dakika; // 0-59 20 int saniye; // 0-59 21 }; 22 23 #endif

61 // Fig. 16.7: fig16_07.cpp 62 // default constructor 16.8 Oluşturucularla Default Argümentlerin Kullanımı 63 // Zaman sınıfı için fonksiyon. 64 #include <iostream> 65 66 using std::cout; 67 using std::endl; 68 69 #include zaman2.h" 70 71 int main() 72 { 73 Zaman t1, // tüm argümentler default-landı 74 t2(2), // dakika ve saniye default-landı 75 t3(21, 34), // saniye default-landı 76 t4(12, 25, 42), // tüm değerler belirlendi 77 t5(27, 74, 99); // tüm geçersiz değerler belirlendi 78 79 cout << Oluşum:\n" 80 << tüm argümentler default:\n "; 81 t1.yazaskeri(); 82 cout << "\n "; 83 t1.yazstandart(); 84 85 cout << "\n saat verildi; dakika ve saniye default:" 86 << "\n "; 87 t2.yazaskeri(); 88 cout << "\n "; 89 t2.yazstandard(); 90 91 cout << "\nsaat ve dakika verildi; saniye default:" 92 << "\n "; SINIFLAR VE VERİ SOYUTLAMASI Nuri 93 ÖZALP (ANKARA t3.yazaskeri(); ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 29

94 cout << "\n "; 95 t3.yazstandard(); 16.8 Oluşturucularla Default Argümentlerin Kullanımı 96 97 cout << "\nsaat, dakika ve saniye verildi:" 98 << "\n "; 99 t4.yazaskeri(); 100 cout << "\n "; 101 t4.yazstandard(); 102 103 cout << "\ngeçersiz değerler verildi:" 104 << "\n "; 105 t5.yazaskeri(); 106 cout << "\n "; 107 t5.yazstandard(); 108 cout << endl; 109 110 return 0; 111 } Oluşum: tüm argümentler default: 00:00 12:00:00 AM saat verildi; dakika ve saniye default: 02:00 2:00:00 AM saat ve dakika verildi; saniye default: 21:34 9:34:00 PM saat, dakika ve saniye verildi: 12:25 12:25:42 PM geçersiz değerler verildi: 00:00 12:00:00 AM Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 30

16.9 Yokedici (Destructor) Kullanımı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 31 Destructor Sınıfın üye fonksiyonu Sistem nesne belleği istemeden sonlandırmayı sağlar constructor ın tümleyenidir Sınıf adından önce tilda (~) yazılır ~Zaman constructor adının sınıf adı olduğunu hatırlayınız Hiç bir parameter almaz, değer göndermez Her sınıf için bir yokedici- çoklu yüklemeye izin yok

16.10 Oluşturucu ve Yokediciler Çağrıldığında Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 32 Oluşturucu ve yokediciler otomatik olarak çağrılır Sıra, nesnelerin hedefine bağlıdır Global hedef nesneleri Oluşturucular diğer fonksiyonlardan önce çağrılır (main dahil) Yokediciler, main bittikten sonra (veya exit fonksiyonu çağrıldıktan sonra) çağrılır Eğer program abort ile sonlanırsa yokedici çağrılmaz

16.10 Oluşturucu ve Yokediciler Çağrıldığında Otomatik yerel nesneler Nesneler tanımlandığında oluşturucu çağrılır Yokedici nesne hedefi terkettiğinde çağrılır (tanımlandıkları bloktan çıkarken) Eğer program exit veya abort ile sonlanırsa yokedici çağrılmaz static yerel nesneler Oluşturucular, program çalışması nesnelerin tanımlandığı noktaya ulaştığında çağrılır Yokediciler, main bittiğinde veya exit fonksiyonu çağrıldığında çağrılır Program abort ile sonlandığında yokedici çağrılmaz Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 33

16.10 Oluşturucu ve Yokediciler Çağrıldığında Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 34 1 // Fig. 16.8: olustur.h 2 // OlusturVeYoket sınıfı tanımı. 3 // Üye fonksiyonlar olustur.cpp de tanımlı 4 #ifndef OLUSTUR_H 5 #define OLUSTUR_H 6 7 class OlusturVeYoket { 8 public: 9 OlusturVeYoket( int ); // constructor 10 ~ OlusturVeYoket(); // destructor 11 private: 12 int data; 13 }; 14 15 #endif

16.10 Oluşturucu ve Yokediciler Çağrıldığında Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 35 16 // Fig. 16.8: olustur.cpp 17 // OlusturVeYoket sınıfı için üye fonksiyonlar tanımı 18 #include <iostream> 19 20 using std::cout; 21 using std::endl; 22 23 #include olustur.h" 24 25 OlusturVeYoket :: OlusturVeYoket( int deger ) 26 { 27 data = deger; 28 cout << Nesne " << data << " constructor"; 29 } 30 31 OlusturVeYoket ::~ OlusturVeYoket() 32 { cout << Nesne " << data << " destructor " << endl; }

33 // Fig. 16.8: fig16_08.cpp 16.10 Oluşturucu ve Yokediciler Çağrıldığında 34 // Oluşturucu ve Yokedicilerin çağrılma sırası 35 // gösterimi. 36 #include <iostream> 37 38 using std::cout; 39 using std::endl; 40 41 #include olustur.h" 42 43 void olustur( void ); // prototip 44 45 OlusturVeYoket ilk( 1 ); // global nesne 46 47 int main() 48 { 49 cout << " (global main den önce oluşturuldu)" << endl; 50 51 OlusturVeYoket ikinci( 2 ); // yerel nesne 52 cout << " (main-de yerel otomatik)" << endl; 53 54 static OlusturVeYoket ucuncu( 3 ); // yerel nesne 55 cout << " (main-de yerel static)" << endl; 56 57 olustur(); // nesne oluşturmak için fonksiyonu çağır 58 59 OlusturVeYoket dorduncu( 4 ); // yerel nesne 60 cout << " (main-de yerel otomatik)" << endl; 61 return 0; 62 } SINIFLAR VE VERİ SOYUTLAMASI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 36

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 37 16.10 Oluşturucu ve Yokediciler Çağrıldığında 63 64 // Nesneler oluşturmak için fonksiyonlar 65 void olustur( void ) 66 { 67 OlusturVeYoket besinci( 5 ); 68 cout << " (olustur-da yerel otomatik)" << endl; 69 70 static OlusturVeYoket altinci( 6 ); 71 cout << " (olustur-da yerel static)" << endl; 72 73 OlusturVeYoket yedinci( 7 ); 74 cout << " (olustur-da yerel otomatik)" << endl; 75 } Nesne 1 constructor (global main den önce oluşturuldu) Nesne 2 constructor (main-de yerel otomatik) Nesne 3 constructor (main-de yerel static) Nesne 5 constructor (olustur-da yerel otomatik) Nesne 6 constructor (olustur-da yerel static) Nesne 7 constructor (olustur-da yerel otomatic) Nesne 7 destructor Nesne 5 destructor Nesne 4 constructor (main-de yerel otomatik) Nesne 4 destructor Nesne 2 destructor Nesne 6 destructor Nesne 3 destructor Nesne 1 destructor

16.11 Veri Üyelerini ve Üye Fonksiyonlarını Kullanma Sınıflar public üye fonksiyonlar sağlarlar private veri üyelerinin değerlerini kur (yani yaz) veya al (yani oku) Üye fonksiyon faizhesapla (BankaHesabi sınıfının bir private veri üyesi ) ile bir banka hesabını ayarlama Adlandırma faizorani nı kuran üye fonksiyon için tipik bir isim kurfaizorani alınabilir faizorani nı alan üye fonksiyon için tipik bir isim alfaizorani alınabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 38

16.11 Veri Üyelerini ve Üye Fonksiyonlarını Kullanma Kurma ve alma kapasitelerini etkili kullanma veri üyelerini public yapar mı? Hayır! Fonksiyonun ne kuracağına ve hangi bilgileri alacağına programcı karar verir public kur fonksiyonu Veri üyelerini düzenleme girişimini kontrol etmeli, O veri için yeni değerin uygunluğunu sağlamalı; Örnek: ayın gününü 37 ye kurma girişimi engellenmeli. Programcı bu özellikleri eklemelidir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 39

16.12 Bir İnce Tuzak: Özel (private) bir Veri Üyesine bir Referans Gönderme Bir nesneye referans Nesne adı ile aynı Bir atama deyiminin sol tarafında kullanılabilir Referans, orjinal nesneyi de değiştirebilen bir değer alabilir Bu kapasiteyi kullanmanın bir yolu (malesef!) Bir private veri üyesine bir const olmayan referans gönderen bir sınıfın bir public üye fonksiyonunu al Bu referans orjinal veriyi değiştirecek şekilde düzenlenebilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 40

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 41 16.12 Bir İnce Tuzak: Özel (private) bir Veri Üyesine bir Referans Gönderme 1 // Fig. 16.10: time4.h 2 // Zaman sınıfı deklarasyonu. 3 // üye fonksiyonlar zaman4.cpp de tanımlı 4 5 // önişlemci komutları 6 // header dosyasının çoklu kullanımını engeller 7 #ifndef ZAMAN4_H 8 #define ZAMAN4_H 9 10 class Zaman { 11 public: 12 Zaman( int = 0, int = 0, int = 0 ); 13 void kurzaman( int, int, int ); 14 int alsaat(); 15 int &geckursaat( int ); // tehlikeli referans döner 16 private: 17 int saat; 18 int dakika; 19 int saniye; 20 }; 21 22 #endif

23 // Fig. 16.10: zaman4.cpp 24 // Zaman sınıfı için üye fonksiyonların tanımı. 25 #include zaman4.h" 26 27 // Private veri girmek için Constructor. 28 // değişkenleri kurmak için kurzaman fonksiyonunu çağırır. 29 // Default değerler 0 (class tanımına bakınız). 30 Zaman::Zaman( int sa, int dk, int sny ) 31 { kurzaman( sa, dk, sny ); } 32 33 // saat dakika ve saniye değerlerini kur. 34 void Zaman::kurZaman( int s, int d, int sn ) 35 { 36 saat = ( s >= 0 && s < 24 )? s : 0; 37 minute = ( d >= 0 && d < 60 )? d : 0; 38 second = ( sn >= 0 && sn < 60 )? sn : 0; 39 } 40 41 // saat değerini al 42 int Zaman::alSaat() { return saat; } 43 44 // ZAYIF PROGRAMLAMA ÖRNEĞĠ: 45 // Private veri üyesine bir referans gönderiyor. 46 int &Zaman::gecKurSaat( int sa ) 47 { 48 saat = ( sa >= 0 && sa < 24 )? sa : 0; 49 50 return saat; // tehlikeli referans dönüyor 51 } Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 42

52 // Fig. 16.10: fig16_10.cpp 53 // public üye fonksiyonu gösterimi 54 // özel veri üyesine referans gönderiyor. 55 // Bu örnekte Zaman sınıfı dağıtıldı. 56 #include <iostream> 57 58 using std::cout; 59 using std::endl; 60 61 #include zaman4.h" 62 63 int main() 64 { 65 Zaman t; 66 int &saatref = t.geckursaat( 20 ); 67 68 cout << Değiştirmeden önce saat: " << saatref; 69 saatref = 30; // geçersiz değerle değiştirme 70 cout << "\ndeğişimden sonra saat: " << t.alsaat(); 71 72 // Tehlikeli: Fonksiyon çağrımı 73 // bir sdeğer olarak kullanılabilecek bir referans gönderir! 74 t.geckursaat(12) = 74; 75 cout << "\n\n*********************************\n" 76 << ZAYIF PROGRAMLAMA ÖRNEĞĠ!!!!!!!!\n" 77 << Sdeğer olarak geckursaat, Saat: " 78 << t.alsaat() 79 << "\n*********************************" << endl; 80 81 return 0; 82 } Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 43

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 44 16.12 Bir İnce Tuzak: Özel (private) bir Veri Üyesine bir Referans Gönderme Deiğtirmeden önce saat: 20 Değişimden sonra saat: 30 ********************************* ZAYIF PROGRAMLAMA ÖRNEĞĠ!!!!!!!! Sdeğer olarak geckursaat, Saat: 74 *********************************

16.13 Default Üyebazlı Kopyayla Atama Atama operatörü (=) Değişkenleri eşitler, yani, x = y; Bir nesneyi aynı tipten bir nesneye atamak için kullanılabilir Üyebazlı kopya üyeden üyeye kopya Nesne1= Nesne2; Nesneler Fonksiyon argümentleri olarak geçebilir Fonksiyonlardan gönderilebilir (default-u ; değer-ile çağırma) Referans ile çağırma için pointer kullan Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 45

16.13 Default Üyebazlı Kopyayla Atama 1 // Fig. 16.11: fig16_11.cpp 2 // default üyebazlı kopya kullanarak 3 // sınıf nesnelerinin birbirlerine atanması 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 // Basit Gün sınıfı 10 class Gun { 11 public: 12 Gun( int = 1, int = 1, int = 2004 ); // default constructor 13 void print(); 14 private: 15 int ay; 16 int gun; 17 int yil; 18 }; 19 20 // Hedef kontrolsüz basit Gun oluşturucusu 21 Gun::Gun( int a, int g, int y ) 22 { 23 ay = a; 24 gun = g; 25 yil = y; 26 } 27 28 // aa-gg-yyyy formunda veriyi yaz 29 void Gun::print() 30 { cout << ay << '-' << gun << '-' << yil; } SINIFLAR VE VERİ SOYUTLAMASI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 46

16.13 Default Üyebazlı Kopyayla Atama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 47 31 32 int main() 33 { 34 Gun gun1( 7, 4, 2003 ), gun2; // g2 default-u 1/1/04 35 36 cout << gun1 = "; 37 gun1.print(); 38 cout << "\ngun2 = "; 39 gun2.print(); 40 41 gun2 = gun1; // default üyebazlı kopya ataması 42 cout << "\n\ndefault üyebazlı kopyadan sonra, gun2 = "; 43 gun2.print(); 44 cout << endl; 45 46 return 0; 47 } gun1 = 7-4-2003 gun2 = 1-1-2004 Default üyebazlı kopyadan sonra, gun2 = 7-4-2003

16.14 Software (Yazılım) Kullanılabilirliği Nesne-tabanlı programlama Kullanışlı sınıflar oluşturma konsantrasyonu Sınıflara hakim olmak ve kataloglamak için olağanüstü fırsatlar Her çaptan programcının erişebilirliği Class kütüphaneleri bu amaç için oluşturulur Software Varolan, iyi-tanımlı, dikkatlice test edilmiş, kullanışlı, geniş-çaplı ulaşılabilir parçalar Güçlü ve yüksek kalite yazılımda hız gelişimi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SINIFLAR VE VERİ SOYUTLAMASI 48

Bölüm 17 - C++ Sınıfları: Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 1 İçerik 17.1 Giriş 17.2 const (sabit) Nesneler ve const Üye Fonksiyonları 17.3 Kompozisyon: Sınıf Üyeleri Olarak Nesneler 17.4 friend Fonksiyonları ve friend Sınıfları 17.5 this Pointer Kullanımı 17.6 new ve delete Operatörleri ile Dinamik Bellek Düzenleme 17.7 static Class Üyeleri 17.8 Data Soyutlama ve Bilgi Gizleme 17.8.1 Örnek: Dizi Soyut Veri Tipi 17.8.2 Örnek: String Soyut Veri Tipi 17.8.3 Örnek: Sıra Soyut Veri Tipi 17.9 İçerici Sınıfları ve Öteleyiciler

17.1 Giriş Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 2 Bölüm 16-18 Nesne-tabanlı programlama Bölüm 19-20 Polimorfizm ve kalıtsallık Nesne-tabanlı programlama

17.2 const (sabit) Nesneler ve const Üye Fonksiyonları Enaz ayrıcalık prensibi Sadece gereksinim duyulan nesnelere izin verilir, daha fazlasına yok const anahtarkelime Nesnenin değiştirilemeyeceğini belirtir Değiştirilmeye kalkılırsa syntax hatası verir Örnek: const zaman ogle( 12, 0, 0 ); zaman sınıfından ogle adlı bir const nesne deklare eder ve ogle ye 12 değerini atar Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 3

17.2 const (sabit) Nesneler ve const Üye Fonksiyonları const nesneler const fonksiyonlar gerektirir const deklarasyonlu fonksiyonlar nesneyi değiştiremez const fonksiyon prototipinde ve tanımında belirtilir Prototip: ReturnTipi FonksiyonAdı (param1,param2 ) const; Tanım: ReturnTipi FonksiyonAdı (param1,param2 ) const { }; Örnek: int A::alDeger() const {return ozelveriuyesi}; -Bir veri üyesini gönderir, uygun şekilde const olarak deklare edilmiştir -Constructor / Destructor const olamaz -Değişkenleri belirlemeleri gerekir (bu nedenle de değiştirebilirler) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 4

17.2 const (sabit) Nesneler ve const Üye Fonksiyonları 1 // Fig. 17.1: time5.h 2 // Zaman sınıfı dekarasyonu. 3 // üye fonksiyonlar zaman5.cpp de tanımlı 4 #ifndef ZAMAN5_H 5 #define ZAMAN5_H 6 7 class Zaman { 8 public: 9 Zaman( int = 0, int = 0, int = 0 ); // default constructor 10 11 // fonksiyonları kur 12 void kurzaman( int, int, int ); 13 void kursaat( int ); 14 void kurdakika( int ); 15 void kursaniye( int ); 16 17 // fonksiyonları al (const olarak deklare edilmiş) 18 int alsaat() const; // saati gönder 19 int aldakika() const; // dakikayı gönder 20 int alsaniye() const; // saniyeyi gönder 21 22 // fonksiyonları yaz 23 void yazaskeri() const; // askeri zamanı yaz 24 void yazstandard(); // standard zamanı yaz 25 private: 26 int saat; // 0-23 27 int dakika; // 0-59 28 int saniye; // 0-59 29 }; 30 31 #endif C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 5

17.2 const (sabit) Nesneler ve const Üye Fonksiyonları 32 // Fig. 17.1: zaman5.cpp 33 // Zaman sınıfı için üye fonksiyonların tanımı. 34 #include <iostream> 35 36 using std::cout; 37 38 #include zaman5.h" 39 40 // özel veri girmek için Constructor fonksiyonu. 41 // Default değerler 0 (sınıf tanımına bak). 42 Zaman::Zaman( int sa, int dak, int sny ) 43 { kurzaman( sa, dak, sny ); } 44 45 // saat saniye ve dakika değerlerini kur. 46 void Zaman::kurZaman( int s, int d, int sn ) 47 { 48 kursaat( s ); 49 kurdakika( d ); 50 kursaniye( sn ); 51 } 52 53 // saat değerini kur 54 void Zaman::kurSaat( int s ) 55 { saat = ( s >= 0 && s < 24 )? s : 0; } 56 57 // dakika değerini kur 58 void Zaman::kurDakika( int d ) 59 { dakika = ( d >= 0 && d < 60 )? d : 0; } 60 61 // saniye değerini kur 62 void Zaman::kurZaman( int sn ) 63 { saniye = ( sn >= 0 && sn < 60 )? sn : 0; } C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 6

64 65 // saat değerini al 66 int Zaman::alSaatr() const { return saat; } 67 68 // dakikayı al 69 int Zaman::alDakika() const { return dakika; } 70 71 // saniyeyi al 72 int Zaman::alSaniye() const { return saniye; } 73 74 // askerri formatta göster: SS:DD 75 void Zaman::yazAskeri() const 76 { 77 cout << ( saat < 10? "0" : "" ) << saat << ":" 78 << ( dakika < 10? "0" : "" ) << dakika; 79 } 80 81 // standard formatta göster: SS:DD:SS AM (or PM) 82 void Zaman::yazStandard() // const olmalı 83 { 84 cout << ( ( saat == 12 )? 12 : saat % 12 ) << ":" 85 << ( dakika < 10? "0" : "" ) << dakika << ":" 86 << ( saniye < 10? "0" : "" ) << saniye 87 << ( saat < 12? " AM" : " PM" ); 88 } C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 7

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 8 17.2 const (sabit) Nesneler ve const Üye Fonksiyonları 89 // Fig. 17.1: fig17_01.cpp 90 // const olmaya üye fonksiyon ile 91 // const bir nesneye erişim denemesi 92 #include zaman5.h" 93 94 int main() 95 { 96 Zaman kalk( 6, 45, 0 ); // non-constant NESNE 97 const Zaman ogle( 12, 0, 0 ); // constant NESNE 98 99 // ÜYE FONKSİYON NESNESİ 100 kalk.kursaat( 18 ); // non-const non-const 101 102 ogle.kursaat( 12 ); // non-const const 103 104 kalk.alsaat(); // const non-const 105 106 ogle.aldakika(); // const const 107 ogle.yazaskeri; // const const 108 ogle.yazstandard(); // non-const const 109 return 0; 110 } Compiling... Fig07_01.cpp d:fig07_01.cpp(14) : error C2662: kursaat' : cannot convert 'this' pointer from 'const class Zaman' to 'class Zaman &' Conversion loses qualifiers d:\fig07_01.cpp(20) : error C2662: yazstandard' : cannot convert 'this' pointer from 'const class Zaman' to 'class Zaman &' Conversion loses qualifiers Zaman5.cpp Error executing cl.exe. test.exe - 2 error(s), 0 warning(s)

17.2 const (sabit) Nesneler ve const Üye Fonksiyonları Üye belirleyici (ilk atayıcı) dizini Artir sınıfında artir üyesi Artir için oluşturucu aşağıdaki gibi düzenlenebilir: Artir::Artir( int c, int i ) : artir( i ) { say = c; } ": artir( i )" artir ı i nin değerine getirir. Herhangi veri üysine üye belirleme dizini ile ilk atama yapılabilir const-lara ve referanslara bu yolla ilk atamalar yapılmalıdır Çoklu üye belirleme İki noktadan sonra aralarında virgüller kullan Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 9

17.2 const (sabit) Nesneler ve const Üye Fonksiyonları 1 // Fig. 17.2: fig17_02.cpp 2 // Bir hazır-veri tipi belirlemek için 3 // üye belirleyici kullanımı. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 class Artir { 10 public: 11 Artir( int c = 0, int i = 1 ); 12 void ekleartir() { say+= artir; } 13 void print() const; 14 15 private: 16 int say; 17 const int artir; // const data üyesi 18 }; 19 20 // Artir sınıfı için oluşturucu 21 Artir::Artir( int c, int i ) 22 : artir( i ) // const üye için belirleyici 23 { say = c; } 24 25 // Veriyi yaz 26 void Artir::print() const 27 { 28 cout << say = " << say 29 << ", artır = " << artir << endl; 30 } 31 32 int main() C++ SINIFLARI - Kısım II Nuri 33 ÖZALP { (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 10

17.2 const (sabit) Nesneler ve const Üye Fonksiyonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 11 34 Artir deger( 10, 5 ); 35 36 cout << Artıştan önce: "; 37 deger.print(); 38 39 for ( int j = 0; j < 3; j++ ) { 40 deger.ekleartis(); 41 cout << j+1 << Artıştan sonra " << ": "; 42 deger.print(); 43 } 44 45 return 0; 46 } Artıştan önce: say= 10, artır= 5 1 artıştan sonra: say= 15, artır= 5 2 artıştan sonra: say= 20, artır= 5 3 artıştan sonra: say= 25, artır= 5

17.3 Kompozisyon: Sınıf Üyeleri Olarak Nesneler Kompozisyon Sınıf, üye olarak diğer sınıfların nesnelerine sahiptir Nesnelerin oluşturulması Üye nesneler deklarasyon sırasına göre oluşturulur Oluşturucunun üye belirteç sırasına göre değil Parantez içi sınıf nesnelerinden (evsahibi nesneler) önce oluşturulur Oluşturucular en içten dışa çağrılır Yokediciler en dıştan içe çağrılır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 12

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 13 17.3 Kompozisyon: Sınıf Üyeleri Olarak Nesneler Örnek: Isci::Isci( char *iadi, char *sadi, int day, int dgun, int dyil, int gay, int ggun, int gyil ) : dogumgunu( day, dgun, dyil), girisgunu( gay, ggun, gyil) Gun sınıfından nesneleri (DogumGunu ve girisgunu) Isci sınıfına ekle dogumgunu ve girisgunu üye belirleyicilere sahiptir- muhtemelen Isci sınıfında const-dırlar

1 // Fig. 17.4: gun1.h 2 // Gun sınıfı deklarasyonu. 3 // üye fonksiyonlar gun1.cpp de tanımlı 4 #ifndef GUN1_H 5 #define GUN1_H 6 7 class Gun { 8 public: 9 Gun( int = 1, int = 1, int = 1900 ); // default constructor 10 void yaz() const; // ay/gün/yıl formatında Günü yaz 11 ~Gun(); // yoketme sırasını kontrol et 12 private: 13 int ay; // 1-12 14 int gun; // 1-31 based on month 15 int yil; // any year 16 17 // uygun ay ve gün kontrolü için kullanım fonksiyonu 18 int gunkontrol( int ); 19 }; 20 21 #endif C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 14

22 // Fig. 17.4: gun1.cpp 23 // Gun sınıfı için üye fonksiyonların tanımı. 24 #include <iostream> 25 26 using std::cout; 27 using std::endl; 28 29 #include gun1.h" 30 31 // Constructor: ay için uygun değer kontrolü; 32 // uygun değer için kullanım fonksiyonu 33 // gunkontrol ü çağır. 34 Gun::Gun( int a, int gn, int yl ) 35 { 36 if ( a > 0 && a <= 12 ) // ayı doğrula 37 ay = a; 38 else { 39 ay = 1; 40 cout << Ay " << a << " geçersiz. Ay 1 alındı.\n"; 41 } 42 43 yil = yl; // yıl doğru olmalı 44 gun = gunkontrol( gn ); // gunu doğrula 45 46 cout << gun için Gun nesne oluşturucusu"; 47 print(); // ilginç: argumentsiz print 48 cout << endl; 49 } 50 C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 15

51 // Gun nesnesini ay/gun/yıl formatında yaz 52 void Gun::print() const 53 { cout << ay << '/' << gun << '/' << yil; } 54 55 // Destructor: 56 Gun::~Gun() 57 { 58 cout << gun için Gun nesne yokedicisi "; 59 print(); 60 cout << endl; 61 } 62 63 // Kullanım fonksiyonu 64 // Ay ve yıla göre. 65 // 2000 atlama yılı mı? 66 int Gun::gunKontrol( int guntest ) 67 { 68 static const int herayicingunler[ 13 ] = 69 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 70 71 if ( guntest > 0 && guntest <= herayicingunler[ ay ] ) 72 return guntest; 73 74 if ( ay == 2 && // Şubat: Atlama yılı kontrolü 75 guntest == 29 && 76 ( yil % 400 == 0 77 ( yil % 4 == 0 && yil % 100!= 0 ) ) ) 78 return guntest; 79 80 cout << Gün " << guntest << " geçersiz. Gün 1 alındı.\n"; 81 82 return 1; // kötü değer varsa nesneyi uygun değerde bırak C++ SINIFLARI - Kısım II Nuri 83 ÖZALP } (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 16

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 17 84 // Fig. 17.4: is1.h 85 // Isci sınıfı dekarasyonu. 86 // Üye fonksiyonlar is1.cpp de tanımlı 87 #ifndef IS1_H 88 #define IS1_H 89 90 #include gun1.h" 91 92 class Isci { 93 public: 94 Isci( char *, char *, int, int, int, int, int, int ); 95 void print() const; 96 ~İsci(); // yokedici 97 private: 98 char ilkad[ 25 ]; 99 char soyad[ 25 ]; 100 const Gun dogumgunu; 101 const Gun girisgunu; 102}; 103 104#endif

105 // Fig. 17.4: is1.cpp 106 // Isci sınıfı için üye fonksiyon tanımları. 107 #include <iostream> 108 109 using std::cout; 110 using std::endl; 111 112 #include <cstring> 113 #include is1.h" 114 #include gun1.h" 115 116 İsci::İsci( char *iadi, char *sadi, 117 int day, int dgun, int dyil, 118 int gay, int ggun, int gyil ) 119 : dogumgunu( day, dgun, dyil ), 120 GirisGunu( gay, ggun, gyil ) 121 { 122 // iadi nı ilkad a kopyala ve uzunluğun yettiğini kontrol et 123 int boy = strlen( iadi ); 124 boy = ( boy < 25? boy : 24 ); 125 strncpy( ilkad, iad, boy ); 126 ilkad[ boy] = '\0'; 127 128 // copy lname into lastname and be sure that it fits 129 boy = strlen( sadi ); 130 boy = ( boy < 25? boy : 24 ); 131 strncpy( soyad, sadi, boy ); 132 soyad[ boy ] = '\0'; 133 134 cout << İşçi nesne oluşturucu: " 135 << ilkad << ' ' << soyad << endl; 1. header dosyaları yükle 1.1 fonks tanımları 1.2 Isci constructor 1.2.1 const Gun üyeleri için üye belirleyici dizini kullan C++ SINIFLARI - Kısım II Nuri 136 ÖZALP } (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 18

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 19 137 138 void Isci::print() const 139{ 140 cout << soyad << ", " << ilkad << "\n Giriş: "; 141 girisgunu.print(); 142 cout << " Doğum günü: "; 143 dogumgunu.print(); 144 cout << endl; 145} 146 147// Destructor: 148 Isci::~Isci() 149{ 150 cout << Isci nesnesi yokedicisi: " 151 << soyad << ", " << ilkad << endl; 152} 1.3 print tanımı 1.4 Isci destructor

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 20 153// Fig. 17.4: fig17_04.cpp 1. header dosyalarını yükle 154// Kompozisyon gösterimi: nesne üyeli bir nesne. 2. Isci nesnesi yarat 155#include <iostream> 156 2.1 Geçersiz Gun dene 157 using std::cout; 158 using std::endl; 159 160#include is1.h" 161 162 int main() 163{ 164 İsci i( Ali", Güner", 7, 24, 1949, 3, 12, 1988 ); 165 166 cout << '\n'; 167 i.print(); 168 169 cout << "\ngun oluşturucuyu geçersiz değer ile test et:\n"; 170 Gun g( 14, 35, 1994 ); // geçersiz gün 171 cout << endl; 172 return 0; 173}

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 21 Gun için Gun nesne oluşturucusu: 7/24/1949 Gun için Gun nesne oluşturucu: 3/12/1988 İşci nesne oluşturucusu: Ali Güner Güner, Ali Giriş: 3/12/1988 Doğum günü: 7/24/1949 Gun oluşturucuyu geçersiz değer ile test et: Ay 14 geçersiz. Ay 1 alındı. Gün 35 geçersiz. Gün 1 alındı. Gun için Gun nesne oluşturucusu: 1/1/1994 Gun için Gun nesne yokedicisi 1/1/1994 İşçi nesnesi yokedicisi: Güner, Ali Gun için Gun nesne yokedicisi 3/12/1988 Gun için Gun nesne yokedicisi 7/24/1949

17.4 friend Fonksiyonları ve friend Sınıfları friend fonksiyonu ve friend sınıfı Bir başka sınıfın private ve protected (sonra verilecek) üyelerine erişim sağlar friend fonksiyonları sınıfın üye fonksiyonları değildir Özellikleri Sınıf kapsamının dışında tanımlanır Arkadaşlık verilir, alınmaz Simetrik değildir (B, A nın arkadaşı ise A, B nin arkadaşı olmak zorunda değildir) Geçişken değildir (A, B nin B de C nin arkadaşı ise A, C nin arkadaşı olmak zorunda değildir) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 22

17.4 friend Fonksiyonları ve friend Sınıfları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 23 friend deklarasyonu friend fonksiyonu Sınıftaki arkadaşlığı sağlayan fonksiyon prototipinden önce friend yaz. friend int fonksiyonum( int x ); Arkadaşlığı sağlayan sınıfta görülür friend sınıfı Arkadaşlığı sağlayan sınıfta friend class sınıfadı yaz SınıfBir, Sınıfİki ye arkadaşlık sağlıyorsa, friend class Sınıfİki; SınıfBir tanımında yer almalıdır

1 // Fig. 17.5: fig17_05.cpp 17.4 friend Fonksiyonları ve friend Sınıfları 2 // Arkadaşlar sınıfın özel (private) üyelerine erişim sağlayabilir. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 // Say sınıfını değştir 9 class Say { 10 friend void setx( Say &, int ); // friend deklarasyonu 11 public: 12 Say() { x = 0; } // constructor 13 void print() const { cout << x << endl; } // çıktı 14 private: 15 int x; // veri üyesi 16 }; 17 18 // Say ın özel üyesini değiştirebilir çünkü 19 // setx Say ın bir arkadaş fonksiyonu olarak deklare edildi 20 void setx( Say &c, int deg ) 21 { 22 c.x = deg; // legal: setx Say ın arkadaşı 23 } 24 25 int main() 26 { 27 Say sayac; 28 29 cout << sayac.x sabitlemeden sonra: "; 30 sayac.print(); 1. Class tanımı 1.1 friend fonksiyonu deklarasyonu 1.2 Fonk tanımı 1.3 Say nesnesini belirle C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 24

17.4 friend Fonksiyonları ve friend Sınıfları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 25 31 cout << sayac.x setx arkadaş fonksiyonunu çağırdıkran sonra: "; 32 setx( sayac, 8 ); 33 sayac.print(); 34 return 0; 2. Nesneyi değiştir 3. Yaz 35 } Çıktı sayac.x sabitlenmeden sonra: 0 sayac.x setx arkadaş fonksiyonunu çağırdıktan sonra: 8

1 // Fig. 17.6: fig17_06.cpp 17.4 friend Fonksiyonları ve friend Sınıfları 2 // Friend olmayan/üye olmayan fonksiyonlar 3 // sınıfın private verisine erişim sağlayamaz. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 // değiştirilmiş Say sınıfı 10 class Say { 11 public: 12 Say() { x = 0; } // constructor 13 void print() const { cout << x << endl; } // output 14 private: 15 int x; // data üyesi 16 }; 17 18 // Fonksiyon Say sınıfının özel veri üyesini değiştirmeye çalışıyor, 19 // fakat olmaz çünkü Say ın bir arkadaşı değildir. 20 void olmazsetx( Say &c, int deg) 21 { 22 c.x = deg; // HATA: Say::x' erişilemez 23 } 24 25 int main() 26 { 27 Say sayac; 28 29 olmazsetx( sayac, 3 ); // olmazsetx arkadaş değildir 30 return 0; 31 } (Önceki program friend deklarasyonu yapılmamış hali) C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 26

17.4 friend Fonksiyonları ve friend Sınıfları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 27 Compiling... Fig07_06.cpp E:\cpp\Böl17\Fig07_06\Fig07_06.cpp(22) : error C2248: 'x' : cannot access private member declared in class Say' E:\cpp\Böl17\Fig07_06\ Fig07_06.cpp(15) : see declaration of 'x' Error executing cl.exe. test.exe - 1 error(s), 0 warning(s)

17.5 this Pointer Kullanımı - this pointer - Nesnelerin kendi adreslerine erişimini sağlar - Kendi başına nesnenin bir parçası değildir - non-static üye fonksiyonundaki ilk kapalı argüment nesneyi çağırır - Üye veri ve fonksiyonlarını dolaylı olarak referans yapar - Örnek: class Isci - non-const üye fonksiyonlar için: Isci * const yaz - Bir Isci nesnesine bir sabit pointer - const üye fonksiyonlar için: const Isci* const yaz - Bir sabit Isci nesnesine bir sabit pointer Ardışık üye ulaşımı fonksiyon çağrımı Fonksiyon aynı nesneye bir referans pointer gönderir {return *this;} O pointer-da diğer fonksiyonlar da çalışabilir Referans göndermeyen fonksiyon en son çağrılmalıdır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 28

17.5 this Pointer Kullanımı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 29 Örnek Üye fonksiyonlar kursaat, kurdakika, ve kursaniye nin tümü *this (bir nesneye referans) gönderir t nesnesi için, örneğin t.kursaat(1).kurdakika(2).kursaniye(3); t.kursaat(1) i işler ve *this (nesneye referans), gönderir ve ifade t.kurdakika(2).kursaniye(3); durumuna gelir t.kurdakika(2)işlemi, referans gönderir, ve t.kursaniye(3); durumuna gelir t.kursaniye(3), işlemi referans gönderir, ve t; durumuna gelir ki, bir etkisi yoktur

1 // Fig. 17.7: fig17_07.cpp 2 // Nesne üyelerini referans vermek için this pointer kullanımı. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 class Test { 9 public: 10 Test( int = 0 ); // default constructor 11 void yaz() const; 12 private: 13 int x; 14 }; 15 16 Test::Test( int a ) { x = a; } // constructor 17 18 void Test::yaz() const // ( ) içinde *this gerekli 19 { 20 cout << " x = " << x 21 << "\n bu->x = " << this ->x 22 << "\n(*bu).x = " << ( * this ).x << endl; 23 } // yaz fonksiyonu sonu 24 25 int main() 26 { 27 Test testnesne( 12 ); 28 29 testnesne.yaz(); 30 31 return 0; 32 } x = 12 bu->x = 12 (*bu).x = 12 C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 30

1 // Fig. 17.8: zaman6.h 2 // Çoklu üye fonksiyon çağrımı. 3 4 // class Zaman deklarasyonu. 5 // Üye fonksiyonlar zaman6.cpp de tanımlı 6 #ifndef ZAMAN6_H 7 #define ZAMAN6_H 8 9 class Zaman { 10 public: 11 Zaman( int = 0, int = 0, int = 0 ); // default constructor 12 13 // fonksiyonları kur 14 Zaman &kurzaman( int, int, int ); // saat, dak., san. kur 15 Zaman &kursaat( int ); // saat kur 16 Zaman &kurdakika( int ); // dak. kur 17 Zaman &kursaniye( int ); // san. kur 18 19 // fonksiyonları kur (normal olarak const tanımlı) 20 int alsaat() const; // saati gönder 21 int aldakika() const; // dak. gönder 22 int alsaniye() const; // san. gönder 23 24 // fonksiyonları yaz (normal olarak const tanımlı) 25 void yazaskeri() const; 26 void yazstandard() const; 27 private: 28 int saat; // 0-23 29 int dakika; // 0-59 30 int saniye; // 0-59 31 }; 32 C++ SINIFLARI - Kısım II Nuri 33 ÖZALP #endif (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 31

34 // Fig. 7.8: zaman.cpp 35 // Zaman class ı için üye fonksiyon tanımları 36 #include <iostream> 37 38 using std::cout; 39 40 #include zaman6.h" 41 42 // Constructor fonksiyonu; private veriyi girmek için 43 // üye fonksiyon değişkenleri kurmak için kurzaman- ı çağırır. 44 // Default değerler 0 (class tanımına bak). 45 Zanan::Zaman( int sa, int dak, int sny ) 46 { kurzaman( sa, dak, sny ); } 47 48 // Saat dak ve san değerlerini kur. 49 Zaman &Zaman::kurZaman( int s, int d, int sn ) 50 { 51 kursaat( s ); 52 kurdakika( d ); 53 kursaniye( sn ); 54 return *this; // ardışık ulaşım sağlar 55 } 56 57 // Saati kur 58 Zaman &Zaman::kurSaat( int s ) 59 { 60 saat = ( s >= 0 && s < 24 )? s : 0; 61 62 return *this; // ardışık ulaşım sağlar 63 } C++ SINIFLARI - Kısım II Nuri 64 ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 32

65 // dak kur 66 Zaman &Zaman::kurDakika( int d ) 67 { 68 dakika = ( d >= 0 && d < 60 )? d : 0; 69 70 return *this; // ardışık ulaşım sağlar 71 } 72 73 // Saniye değerini kur 74 Zaman &Zaman::kurSaniye( int sn ) 75 { 76 saniye = ( sn >= 0 && sn < 60 )? sn : 0; 77 78 return *this; // ardışık ulaşım sağlar 79 } 80 81 // Saati al 82 int Zaman::alSaat() const { return saat; } 83 84 // dak al 85 int Zaman::alDakika() const { return dakika; } 86 87 // Saniyeyi al 88 int Zaman::alSaniye() const { return saniye; } 89 90 // Askeri zamanı görüntüle: SS:DD 91 void Zaman::yazAskeri() const 92 { 93 cout << ( saat < 10? "0" : "" ) << saat << ":" 94 << ( dakika < 10? "0" : "" ) << dakika; C++ SINIFLARI - Kısım II Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 33

95 } 96 97 // Standart formatta zamanı yaz: SS:DD:SS AM (veya PM) 98 void Zaman::yazStandard() const 99 { 100 cout << ( ( saat == 0 saat == 12 )? 12 : saat % 12 ) 101 << ":" << ( dakika < 10? "0" : "" ) << dakika 102 << ":" << ( saniye < 10? "0" : "" ) << saniye 103 << ( saat < 12? " AM" : " PM" ); 104 } 105 // Fig. 17.8: fig17_08.cpp 106 // this pointer ile ardışık üye fonksiyonları çağrımı 107 // 108 #include <iostream> 109 110 using std::cout; 111 using std::endl; 112 113 #include zaman6.h" 114 115 int main() 116 { 117 Zaman t; 118 119 t.kursaat( 18 ).kurdakika( 30 ).kursaniye( 22 ); 120 cout << Askeri format: "; 121 t.yazaskeri(); 122 cout << "\nstandard format: "; 123 t.yazstandard(); 124 125 cout << "\n\nyeni standard zaman: "; C++ SINIFLARI - Kısım II Nuri 126ÖZALP (ANKARA t.kurzaman( ÜNİVERSİTESİ) 20, İLERİ PROGRAMLAMA 20, 20 ).yazstandard(); 34

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 35 127 cout << endl; 128 129 return 0; 130} Askeri format: 18:30 Standard format: 6:30:22 PM Yeni standard zaman: 8:20:20 PM

17.6 new ve delete Operatörleri ile Dinamik Bellek Düzenleme new ve delete C deki malloc ve free den daha iyi dinamik bellek düzenleme new otomatik olarak uygun boyutta nesneler üretir, constructor çağırır, doğru tipe pointer gönderir delete nesneyi siler ve belleği boşaltır Örnek: TipAdı *tipadıptr; Bir TipAdı nesnesine pointer oluşturur tipadıptr = yeni TipAdı; new TipAdı nesnesi oluşturur, pointer gönderir ( tipadıptr ye eşitlenen) delete tipadıptr; TipAdı nesnesi için destructor çağırır ve belleği serbest bırakır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 36

17.6 new ve delete Operatörleri ile Dinamik Bellek Düzenleme Nesneleri belirleme double *nesneptr = new double( 3.14159 ); double tipi nesneye 3.14159 değerini yükler int *diziptr = new int[ 10 ]; 10 elemanlı int dizisi oluşturur, diziptr ye yükler. Dizileri silmek için delete [] diziptr; kullan Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 37

17.7 static Class Üyeleri static class üyeleri Bir sınıfın tüm nesneleri tarafından paylaşılır Normalde, her nesne her bir değişkeninin kendi kopyasını alır Verinin tek bir kopyasının yeterli olması durumularında etkilidir Sadece static değişken güncellenmelidir Global değişkenlere benzer, class hedefe sahiptir Sadece aynı sınıftan nesnelere erişilebilir Dosya hedefinde başlangıç ataması yapılır Sınıfın hiç bir nesnesi olmasa bile vardır Değişken veya fonksiyon olabilir public, private, veya protected Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 38

17.7 static Class Üyeleri static üyelere erişim public static değişkenler: sınıfın herhangi bir nesnesinden erişilebilir Veya sınıf adı ve (::) kullan Isci::say private static değişkenler: bir public static üye fonksiyon kullanılmalıdır. Sınıf adına bir önek ve (::) İsci::alSay() static üye fonksiyonlar non-static veri veya fonksiyonlara erişim sağlayamaz this pointer olmaz, fonksiyon nesnelerden bağımsız olarak vardır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 39

17.7 static Class Üyeleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 40 1 // Fig. 17.9: is1.h 2 // Bir İsci class-ı 3 #ifndef IS1_H 4 #define IS1_H 5 6 class Isci { 7 public: 8 Isci( const char*, const char* ); // constructor 9 ~Isci(); // destructor 10 const char *alilkad() const; // İlk adı gönderir 11 const char *alsoyad() const; // soyadı gönderir 12 13 // static üye fonksiyonu 14 static int getsay(); // nesne sayısını gönderir 15 16 private: 17 char *ilkad; 18 char *soyad; 19 20 // static data üyesi 21 static int say; // verilen nesne sayısı 22 }; 23 24 #endif

25 // Fig. 17.9: is1.cpp 26 // Isci classı için üye fonk. tanımı 17.7 static Class Üyeleri 27 #include <iostream> 28 29 using std::cout; 30 using std::endl; 31 32 #include <cstring> 33 #include <cassert> 34 #include is1.h" 35 36 // static veri üyesini gir 37 int Isci::say = 0; 38 39 // static üye fonksiyonu tanımla 40 // Verilen işçi nesnesi sayısını gönderir. 41 int Isci::alSay() { return say; } 42 43 // Constructor ilk ve soy ad için dinamik bellek düzenler 44 // ilk ve soy adı nesneye kopyalamak için 45 // strcpy yi kullanır 46 Isci::Isci( const char *ilk, const char *soy ) 47 { 48 ilkad = new char[ strlen( ilk ) + 1 ]; 49 assert( ilkad!= 0 ); // bellek düzenlenmesinden emin ol 50 strcpy( ilkad, first ); 51 52 soyad = new char[ strlen( soy ) + 1 ]; 53 assert( soyad!= 0 ); // bellek düzenlenmesinden emin ol garant 54 strcpy( soyad, soy ); 55 C++ SINIFLARI - Kısım II Nuri 56 ÖZALP (ANKARA ++say; ÜNİVERSİTESİ) // static İLERİ PROGRAMLAMA say ı artır 41

57 cout << ilkad << ' ' << soyad << için " 58 << " işçi oluşturucu çağrıldı." << endl; 17.7 static Class Üyeleri 59 } 60 61 // Destructor dinamik düzenlenmiş belleği kaldırır 62 Isci::~Isci() 63 { 64 cout << "~Isci() " << ilad 65 << ' ' << soyad << " için çağrıldı" << endl; 66 delete [] ilkad; // belleği temizle 67 delete [] soyad; // bellği temizle 68 --say; // static say işçi sayısını azalt 69 } 70 71 // İşçinin ilk adını gönder 72 const char *Isci::alilkAd() const 73 { 74 // return tipinden önceki Const, kullanıcının özel veriyi 75 // değiştirmesini engeller. Kullanıcı, tanımlanmamış poiner-ı önlemek 76// için destructor belleği silmeden önce return stringi kopyalamalıdır 77 return ilkad; 78 } 79 80 // Soyadı gönder 81 const char *Isci::alSoyAd() const 82 { 83 // return tipinden önceki Const, kullanıcının özel veriyi 84 // değiştirmesini engeller. Kullanıcı, tanımlanmamış poiner-ı önlemek 85// için destructor belleği silmeden önce return stringi kopyalamalıdır 86 return soyad; C++ SINIFLARI - Kısım II Nuri 87 ÖZALP } (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 42

88 // Fig. 17.9: fig17_09.cpp 89 // Isci class-ı için test sürücü 17.7 static Class Üyeleri 90 #include <iostream> 91 92 using std::cout; 93 using std::endl; 94 95 #include is1.h" 96 97 int main() 98 { 99 cout << Verilerden önce işçi sayısı: " 100 << Isci::alSay() << endl; // class adı kullan 101 102 Isci *i1ptr = new Isci( Ayşe", Yalın" ); 103 Isci *i2ptr = new Isci( Ali", Kemaloğlu" ); 104 105 cout << Verilerden sonra işçi sayısı:" 106 << i1ptr->alsay(); 107 108 cout << "\n\nişçi 1: " 109 << i1ptr->alilkad() 110 << " " << i1ptr->alsoyad() 111 << "\nişçi 2: " 112 << i2ptr->alilkad() 113 << " " << i2ptr->alsoyad() << "\n\n"; 114 115 delete i1ptr; // belleği yenile 116 i1ptr = 0; 117 delete i2ptr; // belleği yenile C++ SINIFLARI - Kısım II Nuri 118ÖZALP (ANKARA i2ptr ÜNİVERSİTESİ) = 0; İLERİ PROGRAMLAMA 43

17.7 static Class Üyeleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 44 119 120 cout << Silmeden sonra işçi sayısı: " 121 << Isci::alSay() << endl; 122 123 return 0; 124} Verilerden önce işçi sayısı: 0 Ayşe Yalın için işçi oluşturucu çağrıldı. Ali Kemaloğlu için işçi oluşturucu çağrıldı. Verilerden sonra işçi sayısı: 2 İşçi 1: Ayşe Yalın İşçi 2: Ali Kemaloğlu ~Isci() Ayşe Yalın için çağrıldı ~Isci() Ali Kemaloğlu için çağrıldı Silmeden sonra işçi sayısı: 0

17.8 Data Soyutlama ve Bilgi Gizleme Bilgi gizleme Sınıflar işlem detaylarını kullanıcıdan saklarlar Örnek: stok veri yapısı Veri elemanları bir tabak yığını gibi üstten eklenir ve üstten alınır Son eklenen, ilk atılır (L(ast-I(n)F(irst)O(ut)) veri yapısı Kullanıcı stoğun nasıl işlem gördüğüne aldırmaz, sadece LIFO veri yapısı ister Soyut veri tipleri (ADT) Gerçek hayat nesnelerinin modelleri int, float sayılar için modellerdir Hatalı-sonlu boyut, duyarlılık, v.s. C++ genişletilebilir bir dildir Taban değiştirilemez, fakat yeni veri tipleri oluşturulabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 45

17.8.1 Örnek: Dizi Soyut Veri Tipi Dizi Temel olarak bir pointer veya bellek yerleri Programcı bir ADT dizisi oluşturabilir Yeni kapasiteler İndis alanı kontrolü, dizi atama ve karşılaştırma, dinamik diziler, boyutunu bilen diziler... Yeni sınıflar Bir bireye, küçük bir gruba veya bir firmaya ait olabilir veya standart class kütüphanesine yerleştirilebilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 46

17.8.2 Örnek: String Soyut Veri Tipi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 47 C++ bilinçli olarak seyrek yapılandırmalı dil Performans yüklerini azaltır Dili gereksinim duyulan şey için oluştur, örneğin bir string class-ı Hem uygulama hem de sistem programcılığı için uygun string bir hazır veri tipi değildir Bunun yerine, C++ kullanıcının kendi string class-ını oluşturmasına izin verir

17.8.3 Örnek: Sıra Soyut Veri Tipi Sıra - bir kuyruk Bilgisayar sistemleri tarafından içsel kullanılır Kuyruk simulasyonu yapan programa gereksinim duyarız Sıra iyi-anlaşılabilir bir davranışa sahiptir Sıralama her adımda bir nesneyi sıraya koy Sıradan çıkar istendiğinde, her adımda bir nesneyi sıradan çıkar İşlemler kullanıcıdan gizlenir Sıra ADT kararlı içsel veri yapısı Kullanıcı veri yapısını doğrudan kullanamayabilir Sadece sıra üye fonksiyonları iç veriye ulaşabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 48

17.9 İçerici Sınıfları ve Öteleyiciler İçerici sınıfları (kolleksiyon sınıfları) Nesne kolleksiyonunu tutmak için oluşturulan sınıflar Bir ögeyi ekleme, silme, arama, sıralama, ve test etme gibi servisler Örnekler: Diziler, stoklar, sıralar, ağaçlar ve erişim listeleri Öteleyici nesneler (öteleyiciler) Bir kolleksiyonun (veya bir eylemin) bir sonraki ögesini gönderen nesneler Her bir içericide bir çok öteleyici olabilir Çoklu göstergeçli( kalınan sayfayı gösteren karton şerit) kitap Her bir öteleyici kendi pozisyon bilgisini saklar Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ SINIFLARI - Kısım II 49

Bölüm 18 - Operatör Çoklu-Yükleme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 1 İçerik 18.1 Giriş 18.2 Operatör Yükleme Temelleri 18.3 Kısıtlamalar 18.4 Sınıf Üyeleri olarak operatör fonksiyonları - friend fonksiyonları 18.5 Akış-ekleme ve Akış Çıkarma fonksiyonlarının yüklenmesi 18.6 Unary Operatörler 18.7 Binary Operatörler 18.8 Örnek Çalışma: Bir Dİzi Sınıfı 18.9 Tipler Arası Dönüşüm 18.10 ++ ve -- Yüklemesi

18.1 Giriş Bölüm 16 ve 17 de ADT ler ve Sınıflar (classes) Fonksiyon çağırma notasyonu belli sınıflar için oldukça problemli (özellikle matematiksel sınıflar için) Bu bölümde Sınıf nesneleri ile çalışmak için C++ ın hazır operatörlerini kullanacağız Operatör yükleme Kullanıcı tanımlı nesnelerle geleneksel operatörleri kullan C++ a geçiş için doğrudan ve kolay yol Çok dikkat gerektirir Yükleme yanlış kullanıldığında programı anlamak güçtür Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 2

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 3 18.2 Operatör Yüklemenin Temelleri Okunabilirliği artırmak için çoklu-yükleme kullan Çok fazla ve yanlış kullanımdan kaçın Format Normal şekilde fonksiyon tanımlamasını yap Fonksiyon adı anahtar operator olup yüklenecek olan operatörün sembolü onu takip eder Toplama (+) operatörünü çoklu yüklemek için operator+ kullanılabilir Atama operatörü (=) Fazla olmamak kaydı ile her sınıf için kullanılabilir Üyebazlı atama Aynı şey adres operatörü (&) için de geçerli

18.3 Kısıtlamalar C++ daki çoğu operatör çoklu-yüklenebilir Çoklu-yüklenebilen operatörler + - * / % ^ & ~! = < > += -= *= /= %= ^= &= = << >> >>= <<= ==!= <= >= && ++ -- ->*, -> [] () new delete new[] delete[] Operandların sayısı değiştirilemez Unary operatörler unary, ve binary operatörler binary kalır &, *, + ve operatörlerinin her birinin unary ve binary versiyonları vardır Unary ve binary versiyonlar ayrı ayrı yüklenebilir Yeni operatör oluşturulamaz Sadece varolan operatörleri kullan Hazır (built-in) tipler Operatörleri çoklu-yükleyemezler İki tamsayının toplam tanımını değiştiremezsiniz Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 4

18.4 Class Üyeleri Olarak Operatör Fonksiyonları - friend Fonksiyonları Operatör fonksiyonları Üye yada üye-olmayan fonksiyonlar olabilir Atama operatörlerinin çoklu-yüklemesi yani:(), [], ->,= Operatör bir üye fonksiyon olmalıdır Üye fonksiyon olarak operatör fonksiyonu En soldaki operand sınıfın bir nesnesi (veya nesneye referans) olmalı Eğer sol operand farklı bir tipten ise, operatör fonksiyonu üye-olmayan bir fonksiyon olmalıdır Eğer o sınıfın private veya protected üyelerine doğrudan erişim sağlanıyorsa, üye olmayan operatör fonksiyonu friend olmalıdır Üye-olmayan çoklu-yüklemeli operatör fonksiyonları Operatörün değişimli olmasına izin verir DevTamsayi buyuktamsayi; int tamsayi; buyuktamsayi = tamsayi+ buyuktamsayi; veya buyuktamsayi = buyuktamsayi + tamsayi; Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 5

18.5 Akış-ekleme ve Akış-çıkarma Fonksiyonlarının Yüklenmesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 6 Çoklu-yüklemeli << ve >> operatörleri Sol operandları sırası ile ostream &, ve istream & tipinde olmalıdır Üye-olmayan fonksiyon olmalıdır (sol operand sınıfın bir nesnesi değil) Eğer private veri üyelerine erişebiliyorsa, bir friend fonksiyonu olmak zorundadır

18.5 Akış-ekleme ve Akış-çıkarma Fonksiyonlarının Yüklenmesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 7

18.5 Akış-ekleme ve Akış-çıkarma Fonksiyonlarının Yüklenmesi 1 // Fig. 18.3: fig18_03.cpp 2 // Akış-ekleme ve akış-çıkarma 3 // operatörleri çoklu-yüklemesi. 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 using std::ostream; 10 using std::istream; 11 12 #include <iomanip> 13 14 using std::setw; 15 16 class TelNo { 17 friend ostream &operator<<( ostream&, const TelNo & ); 18 friend istream &operator>>( istream&, TelNo & ); 19 20 private: 21 char alankodu[ 4 ]; // 3-digit alan kodu ve boşluk 22 char bolge[ 4 ]; // 3-digit bölge ve boşluk 23 char hat[ 5 ]; // 4-digit hat ve boşluk 24 }; 25 26 // Çoklu ekleme operatörü ( cout << bazitelno; ile kulllanmak 27 // istiyorsak 28 // üye fonksiyon olamaz). 29 ostream &operator<<( ostream &output, const TelNo &num ) 30 { OPERATÖR ÇOKLU-YÜKLEME Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 8

Akış-ekleme ve Akış-çıkarma Fonksiyonlarının Yüklenmesi 31 output << "(" << num.alankodu << ") " 32 << num.bolge << "-" << num.hat; 33 return output; // cout << a << b << c; ye izin verir 34 } 35 36 istream &operator>>( istream &input, TelNo &num ) 37 { 38 input.atla(); // ( -i atla 39 input >> setw( 4 ) >> num.alankodu; // alan kodu girdisi 40 input.atla( 2 ); // ) i atla ve boşluk 41 input >> setw( 4 ) >> num.bolge; // bolge girdisi 42 input.atla(); // dash (-) yi atla 43 input >> setw( 5 ) >> num.hat; // hattı gir 44 return input; // cin >> a >> b >> c ; ye izin verir 45 } 46 47 int main() 48 { 49 TelNo tel; // tel nesnesi oluştur 50 51 cout << Telefon numarasını gir. (123) 456-7890 gibi:\n"; 52 53 // cin >> tel, >> operatör fonksiyonunu çağırır 54 // çağırma operatörü operator>>( cin, tel ). 55 cin >> tel; 56 57 // cout << tel, << operatör fonksiyonunu çağırır 58 // çağırma operatörü operator<<( cout, tel ). 59 cout << Girilen tel no: " << tel << endl; 60 return 0; 61 } Telefon numarasını gir (123) 456-7890 gibi: (800) 555-1212 Girilen tel no: (800) 555-1212 OPERATÖR ÇOKLU-YÜKLEME Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 9

18.6 Unary Operatörler Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 10 unary operatörleri çoklu-yükleme Kesinlikle gerekli değilse friend fonksiyonlarından ve friend sınıflarından kaçının. friend kullanımı sınıfın içerilmesini bozar. Bir üye fonksiyon olarak: class String { public: bool operator!() const;... };

18.7 Binary Operatörler binary operatörlerin çoklu-yüklenmesi Non-static üye fonksiyonu, tek argüment Üye-olmayan fonksiyon, iki argüment class String { public: const String &operator+=( const String & );... }; Veya Denk olarak y += z; y.operator+=( z ); class String { friend const String &operator+=( String &,const String & );... }; Denk olarak y += z; operator+=( y, z ); Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 11

18.8 Örnek Çalışma: Bir Dizi Sınıfı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 12 Aşağıdakilerin olduğu bir dizi sınıfı oluşturulacak: İndis kontrolü Dizi ataması Boyutlarını bilen diziler Tüm dizilerin << ve >> ile çıktıları == ve!= ile dizilerin karşılaştırılması

18.8 Örnek Çalışma: Bir Dizi Sınıfı 1 // Fig. 18.4: dizi1.h 2 // Basit dizi sınıfı (tamsayılar için) 3 #ifndef DIZI1_H 4 #define DIZI1_H 5 6 #include <iostream> 7 8 using std::ostream; 9 using std::istream; 10 11 class Dizi { 12 friend ostream &operator<<( ostream &, const Dizi & ); 13 friend istream &operator>>( istream &, Dizi & ); 14 public: 15 Dizi ( int = 10 ); // default constructor 16 Dizi( const Dizi & ); // constructor-ı kopyala 17 ~Dizi(); // destructor 18 int alboyut() const; // boyut-u gönder 19 const Dizi &operator=( const Dizi & ); // dizileri ata 20 bool operator==( const Dizi & ) const; // karşılaştır eşitmi? 21 22 // İki dizi eşit ise 23 // true gönder, aksi halde false gönder (operator== kullanıyor). 24 bool operator!=( const Dizi &dogru ) const 25 { return! ( *bu == dogru ); } 26 27 int &operator[]( int ); // indis operator 28 const int &operator[]( int ) const; // indis operator 29 static int aldizisay(); // verilen dizi sayısını 30 // gönder. 31 private: 32 int boyut; // dizi boyutu 33 int *ptr; // dizinin ilk elemanına pointer 34 static int dizisay; // verilen dizi sayısı OPERATÖR ÇOKLU-YÜKLEME 1. Class tanımı 1.1 fonksiyon prototipi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 13

35 }; 36 37 #endif 38 // Fig 18.4: dizi1.cpp 18.8 Örnek Çalışma: Bir Dizi Sınıfı 39 // Dizi sınıfı için üye fonksiyon tanımları 40 #include <iostream> 41 42 using std::cout; 43 using std::cin; 44 using std::endl; 45 46 #include <iomanip> 47 48 using std::setw; 49 50 #include <cstdlib> 51 #include <cassert> 52 #include dizi1.h" 53 54 // dosya hedefinin statik veri üyesini gir 55 int Dizi::diziSay= 0; // henüz nesne yok 56 57 // Dizi sınıfı için default constructor (default boyut 10) 58 Dizi::Dizi( int diziboyut) 59 { 60 boyut = ( diziboyut > 0? diziboyut : 10 ); 61 ptr = new int[ boyut ]; // dizi için yer oluştur 62 assert( ptr!= 0 ); // bellek yetersiz ise dur 63 ++dizisay; 64 65 for ( int i = 0; i < boyut; i++ ) OPERATÖR ÇOKLU-YÜKLEME 1. Header yükle 1.1 fonksiyon tanımı 1.2 dizi constructor-ı Nuri 66 ÖZALP (ANKARA ptr[ ÜNİVERSİTESİ) i ] = İLERİ 0; PROGRAMLAMA // diziyi tanımla 14

18.8 Örnek Çalışma: Bir Dizi Sınıfı 67 } 68 69 // Dizi sınıfı için constructor-ı kopyala 70 // sonsuz döngüyü önlemek için bir referans almalı 71 Dizi::Dizi( const Dizi &ilk ) : boyut( ilk.boyut ) 72 { 73 ptr = new int[ boyut ]; // diziye yer oluştur 74 assert( ptr!= 0 ); // bellek yetersiz ise dur 75 ++dizisay; 76 77 for ( int i = 0; i < boyut; i++ ) 78 ptr[ i ] = ilk.ptr[ i ]; // ilk i nesneye kopyala 79 } 80 81 // Dizi sınıfı için Destructor 82 Dizi::~Dizi() 83 { 84 delete [] ptr; 85 --dizisay; 86 } 87 88 // Dizinin boyutunu al 89 int Dizi::alBoyut() const { return boyut; } 90 91 // çoklu atama operatörü 92 // const return olması : ( a1 = a2 ) = a3 den kaçınır 93 const Dizi &Dizi::operator=( const Dizi &dogru ) 94 { 95 if ( &dogru!= bu ) { // kendine atamayı kontrol et 96 97 // farklı boyutlu diziler için, orjinal sol taraf dizisini 98 // boz, yeni sol taraf dizisini yerleştir. 99 if ( boyut!= dogru.boyut) { 100 delete [] ptr; // yer ayarla OPERATÖR ÇOKLU-YÜKLEME 1.3 Dizi destructor-ı 1.4 operator= (atama) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 15

18.8 Örnek Çalışma: Bir Dizi Sınıfı 101 boyut = dogru.boyut; // bu nesneyi yeniden boyutlandır 102 ptr = new int[ boyut ]; // dizi kopyası için yer ayarla 103 assert( ptr!= 0 ); // yer yoksa dur 104 } 105 106 for ( int i = 0; i < boyut; i++ ) 107 ptr[ i ] = dogru.ptr[ i ]; // diziyi nesneye kopyala 108 } 109 110 return *bu; // x = y = z; ye izin verir 111 } 112 113 // İki dizi boyutu eşit mi? belirle 114 // 115 bool Dizi::operator==( const Dizi &dogru) const 116 { 117 if ( boyut!= dogru.boyut ) 118 return false; // farklı boyutlu diziler 119 120 for ( int i = 0; i < boyut; i++ ) 121 if ( ptr[ i ]!= right.ptr[ i ] ) 122 return false; // diziler eşit değil 123 124 return true; // diziler eşit 125 } 126 127 // non-const Diziler için çoklu yüklemeli indis operatörü 128 // referans return bir soldeğer üretir 129 int &Dizi::operator[]( int indis ) 130 { 131 // indis boyut dışı mı? OPERATÖR ÇOKLU-YÜKLEME 1.5 operator== (eşitlik) 1.6 operator[] (sabit olmayan diziler için indis) Nuri 132ÖZALP (ANKARA assert( ÜNİVERSİTESİ) 0 <= İLERİ indis PROGRAMLAMA && indis < boyut ); 16

133 134 return ptr[ indis ]; // referans return 135 } 136 137 // const diziler için çoklu yüklemeli indis operatörü 138 // const referans return bir sağdeğer üretir 139 const int &Dizi::operator[]( int indis ) const 140 { 141 // indis boyut dışı mı? 142 assert( 0 <= indis && indis < boyut ); 143 144 return ptr[ indis ]; // const referans return 145 } 146 147 // verilen dizi nesnelerinin sayısını gönderir 148 // static fonksiyonlar const olamaz 149 int Dizi::alDiziSay() { return dizisay; } 150 151 // Dizi sınıfı için çoklu yüklemeli girdi operatörü 152 // dizinin tümü girdidir. 153 istream &operator>>( istream &input, Dizi &a ) 154 { 155 for ( int i = 0; i < a.boyut; i++ ) 156 input >> a.ptr[ i ]; 157 158 return input; // cin >> x >> y; e izin verir 159 } 160 161 // Dizi sınıfı için çoklu yüklemeli çıktı operatörü 162 ostream &operator<<( ostream &output, const Dizi &a ) 18.8 Örnek Çalışma: Bir Dizi Sınıfı 1.6 operator[] (const diziler için indis) 1.7 aldizisay 1.8 operator>> (girdi dizisi) 1.9 operator<< (çıktı dizisi) OPERATÖR ÇOKLU-YÜKLEME Nuri 163 ÖZALP { (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 17

164 int i; 165 166 for ( i = 0; i < a.boyut; i++ ) { 167 output << setw( 12 ) << a.ptr[ i ]; 168 169 if ( ( i + 1 ) % 4 == 0 ) // her satırda 4 sayı 170 output << endl; 171 } 172 173 if ( i % 4!= 0 ) 174 output << endl; 175 176 return output; // cout << x << y; a izin verir 177 } 178 // Fig. 18.4: fig18_04.cpp 179 // Dizi sınıfı için ana program 180 #include <iostream> 181 182 using std::cout; 183 using std::cin; 184 using std::endl; 185 186 #include dizi1.h" 187 188 int main() 189 { 190 // henüz nesne yok 191 cout << " Girilen dizi sayısı = " 192 << Dizi::alDiziSay() << '\n'; 193 18.8 Örnek Çalışma: Bir Dizi Sınıfı OPERATÖR ÇOKLU-YÜKLEME 1. Header yükle Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 18

194 // iki dizi oluştur 195 Dizi tam1( 7 ), tam2; 196 cout << " Girilen dizi sayısı = " 197 << Dizi::alDiziSay() << "\n\n"; 198 199 // tam1 boyutunu ve değerlerini yaz 200 cout << " tam1 dizisinin boyutu: " 201 << tam1.alboyut() 202 << "\n Dizi tanımlandıktan sonra:\n" 203 << tam1 << '\n'; 204 205 // tam2 boyut ve değerlerini yaz 206 cout << " tam2 dizisinin boyutu: " 207 << tam2.alboyut() 208 << "\n Dizi tanımlandıktan sonra:\n" 209 << tam2 << '\n'; 210 211 // tam1 ve tam2 yi gir ve yaz 212 cout << " 17 tamsayı gir:\n"; 213 cin >> tam1 >> tam2; 214 cout << " Girdiden sonra diziler:\n" 215 << tam1:\n" << tam11 216 << " tam2:\n" << tam2 << '\n'; 217 218 // çoklu yüklemeli (!=) operatorü kullan 219 cout << " Hesaplıyor: tam1!= tam2\n"; 220 if ( tam1!= tam2 ) 221 cout << " Eşit değiller\n"; 222 223 // tam1 den tam3 dizisini oluştur 224 // boy ve içeriğini yaz 225 Dizi tam3( tam1 ); 18.8 Örnek Çalışma: Bir Dizi Sınıfı OPERATÖR ÇOKLU-YÜKLEME 1.1 nesneleri belirle 2. Fonksiyon çağır Nuri 226ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 19

227 cout << "\n tam3 dizisinin boyutu: " 228 << tam3.alboyut() 18.8 Örnek Çalışma: Bir Dizi Sınıfı 229 << "\n Dizi tanımlandıktan sonra:\n" 230 << tam3 << '\n'; 231 232 // (=) operatörü 233 cout << " tam2 yi tam1 e atıyor:\n"; 234 tam1 = tam2; 235 cout << " tam1:\n" << tam1 236 << " tam2:\n" << tam2 << '\n'; 237 238 // (==) operatörü 239 cout << " Hesaplıyor: tam1 == tam2\n"; 240 if ( tam1 == tam2 ) 241 cout << " Diziler eşit. \n\n"; 242 243 // indis operatörü sağ değer üretir 244 cout << " tam1[5] : " << tam1[ 5 ] << '\n'; 245 246 // indis operatörü soldeğer üretir 247 cout << " tam[5] e 1000 değerini atıyor \n"; 248 tam1[ 5 ] = 1000; 249 cout << " tam1:\n" << tam1 << '\n'; 250 251 // 252 cout << " 1000 değerini tam1[15] e atamayı deniyor" << endl; 253 tam1[ 15 ] = 1000; // HATA: boyut dışı 254 255 return 0; 256 } 2. Fonksiyon çağır 3. Yaz OPERATÖR ÇOKLU-YÜKLEME Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 20

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 21 Girilen dizi sayısı = 0 Girilen dizi sayısı = 2 18.8 Örnek Çalışma: Bir Dizi Sınıfı Tam1 dizisinin boyutu : 7 Dizi tanımlandıktan sonra: 0 0 0 0 0 0 0 Tam2 dizsinin boyutu : 10 Dizi tanımlandıktan sonra: 0 0 0 0 0 0 0 0 0 0 17 tamsayı gir: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Girdiden sonra dizler: tam1: 1 2 3 4 5 6 7 tam2: 8 9 10 11 12 13 14 15 16 17 Hesaplıyor: tam1!= tam2 Eşit değiller Tam3 dizisinin boyutu: 7 Dizi tanımlandıktan sonra: 1 2 3 4 5 6 7

18.8 Örnek Çalışma: Bir Dizi Sınıfı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 22 Tam2 yi tam1 e atıyor: tam11: 8 9 10 11 12 13 14 15 16 17 tam2: 8 9 10 11 12 13 14 15 16 17 Hesaplıyor: tam1 == tam2 Diziler eşit. tam1[5] = 13 tam1[5] e 1000 değerini atıyor tam1: 8 9 10 11 12 1000 14 15 16 17 1000 değerini tam1[15] e atamayı deniyor Assertion failed: 0 <= indis && indis < boyut, file Dizi1.cpp, line 95 abnormal program termination

18.9 Tipler Arası Dönüşüm Dönüştürme (cast) operatörü Nesneleri hazır-tip veya diğer nesnelere dönüştürür Dönüşüm operatörü bir non-static üye fonksiyon olmalıdır. Bir friend fonksiyon olamaz return tipi belirtmeyiniz Kullanıcı-tanımlı class A için A::operator char *() const; // A, char -a A::operator int() const; //A, int -e A::operator digersinif() const; //A, digersinif -a Derleyici (char *) s gördüğünde s.operator char*() -i çağırır Derleyici geçici nesneler oluşturmak için bu fonksiyonları çağırabilir Eğer s char * tipinde değilse için cout << s; A::operator char *() const; çağırır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 23

18.10 ++ ve -- Yüklemesi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA OPERATÖR ÇOKLU-YÜKLEME 24 Önce/sonra-artır/azalt operatörleri Çoklu yüklenebilir Derleyici ikisini nasıl ayırt eder? Çoklu yüklemeli öncül versiyonları unary operatörlerdeki gibi Örneğin ++d1; için d1.operator++(); Soncul versiyonlar Derleyici örneğin d1++; gördüğünde d1.operator++( 0 ); üye fonksiyon çağrımını oluşturur. Prototip: Gun::operator++( int );

Bölüm 19 Kalıtsallık(Inheritance) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 1 İçerik 19.1 Giriş 19.2 Kalıtsallık: Baz ve Türev Sınıfları 19.3 Korunumlu Üyeler 19.4 Baz-Sınıfı Pointer-ları Türev-Sınıfı Pointer-lara atama 19.5 Üye Fonksiyon Kullanımı 19.6 Baz-Sınıfı Üyeleri Türev Sınıfına Yükleme 19.7 Public, Protected and Private Kalıt 19.8 Doğrudan ve Dolaylı Baz-Sınıfları 19.9 Türev Sınıfında Constructor ve Destructor Kullanımı 19.10 Kapalı Türev-Sınıfı Nesneleri Baz-Sınıfı Nesnelere Dönüştürme 19.11 Kalıt ile Yazılım Mühendisliği 19.12 Kompozisyon ve Kalıt 19.13 İlişkileri Kullan ve Bil 19.14 Örnek: Nokta, Daire, Silindir

19.1 Giriş Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 2 Kalıt Varolan sınıflardan yeni sınıflar elde etme Nitelikleri ve davranışları yoketme. Polimorfizm Programları genel tarzda yazar Çok değişik tipten, varolan ve (belirtilmeyen) ilişkili sınıfları kullanır Türev Sınıfı Veri üyelerini ve üye fonksiyonlarını daha önce tanımlanmış bir baz sınıfından kalıt olarak alan sınıf

19.1 Giriş Kalıt Tek kalıt Sınıf, tek bir baz sınıfından kalıtsaldır Çoklu kalıt Sınıf, çoklu baz sınıflarından kalıtsaldır Üç tip kalıt: public: Türev nesneleri baz sınıfı neslerinden erişimlidir (Bu bölümde verilecek) private: Türev nesneleri baz sınıfı neslerinden erişimli değildir protected: Türev sınıfları ve Arkadaşlar baz sınıfının korunumlu üyelerine erişim sağlayabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 3

19.2 Baz ve Türev Sınıfları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 4 Türev sınıfından (alt sınıftan) bir nesne çoğu zaman baz sınıfın (üst sınıfın) bir nesnesidir Baz sınıfı Türev sınıfı Ogrenci Sekil Kredi Calısan Hesap YuksekLisOgr LisansOgr Daire Ucgen Dortgen TasıtKredisi EvKredisi IpotekKredisi OgrUyesi IdariCal BankomatHesabi YatirimHesabi

19.2 Baz ve Türev Sınıfları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 5 public kalıtının uygulanması class KomisyonIsci : public Isci{... }; KomisyonIsci sınıfı Isci sınıfından kalıttır friend fonksiyonlar kalıt değildir Baz sınıfının private üyeleri Türev sınıfından erişilemez

19.3 protected Üyeler protected kalıt public ve private kalıt arasında orta düzey bir koruma Türev-sınıfı üyeler, basitçe üye adlarını kullanarak baz sınıfının public ve protected üyelerini referans verebilirler protected veri içermeyi (parantezi) kırabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 6

19.4 Baz-Sınıfı Üyelerden Türev Sınıfı Yapma Türev sınıfı nesnesi Baz sınıfı nesnesi olarak işlenebilir Tersi doğru değil- baz sınıfı nesnesi türev sınıfı nesnesi değildir Pointer-ı düşürme Bir baz sınıfı pointer-ı türev sınıfı pointer-a dönüştürmek için bir açık atama kullan Pointer tipinin pointer-ın işaretlediği nesne tipiyle aynı olduğundan emin ol turevptr = static_cast< TurevSinifi * > bazptr; Örnek Daire sınıfı baz sınıfı Nokta dan türetilmiştir Bir Daire nesnesini referans vermek için Nokta tipi bir pointer kullanıyoruz ( veya tersi). Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 7

1 // Fig. 19.4: nokta.h 2 // Nokta sınıfı tanımı 3 #ifndef NOKTA_H 4 #define NOKTA_H 5 6 #include <iostream> 7 8 using std::ostream; 9 10 class Nokta { 11 friend ostream &operator<<( ostream &, const Nokta & ); 12 public: 13 Nokta( int = 0, int = 0 ); // default constructor 14 void noktakur( int, int ); // koordinatları oluştur 15 int alx() const { return x; } // x koordinatı 16 int aly() const { return y; } // y koordinatı 17 protected: // sürücü sınıfından ulaşılabilir 18 int x, y; // Nokta-nın x ve y koordinatları 19 }; 20 21 #endif 22 // Fig. 19.4: nokta.cpp 23 // Nokta sınıfı için üye fonksiyonlar 24 #include <iostream> 25 #include nokta.h" 26 27 // Nokta için Constructor 28 Nokta:: Nokta( int a, int b ) { noktakur( a, b ); } 29 30 // Nokta nın x ve y koordinatlarını kur 31 void Nokta ::noktakur( int a, int b ) 32 { 1. Nokta class tanımı ------------- 1. header yükle 1.1 fonksiyon tanımları KALITSALLIK Nuri 33 ÖZALP (ANKARA x = a; ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 8

34 y = b; 35 } 36 37 // Nokta çıktısı (overloaded stream insertion operatörü ile ) 38 ostream &operator<<( ostream &output, const Nokta &p ) 39 { 40 output << '[' << p.x << ", " << p.y << ']'; 41 42 return output; 43 } 44 // Fig. 19.4: daire.h 45 // Daire sınıfı tanımı 46 #ifndef DAIRE_H 47 #define DAIRE_H 48 49 #include <iostream> 50 51 using std::ostream; 52 53 #include <iomanip> 54 55 using std::ios; 56 using std::setiosflags; 57 using std::setprecision; 58 59 #include " nokta.h" 60 61 class Daire : public Nokta { // Daire Nokta-dan kalıttır 62 friend ostream &operator<<( ostream &, const Circle & ); 63 public: 64 // default constructor KALITSALLIK 1.1 fonksiyon tanımları --------------------- 1. Daire class tanımı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 9

65 Daire( double r = 0.0, int x = 0, int y = 0 ); 66 67 void kurycap( double ); // Yarıçapı kur 68 double alycap() const; // yarıçapı gönder 69 double alan() const; // alan hesapla 70 protected: 71 double ycap; 72 }; 1. Daire tanımı -------------------- 1. Header yükle 1.1 fonksiyon tanımları 73 74 #endif 75 // Fig. 19.4: daire.cpp 76 // Daire için üye fonksiyon tanımı 77 #include daire.h" 78 79 // Daire constructer bir üye ilkdeğerleri ile nokta constructer-ı 80 // çağırıyor 81 Daire::Daire( double r, int a, int b ) 82 : Nokta( a, b ) // baz-class constructor çağırır 83 { kurycap( r ); } 84 85 // Daire yarıçapını kur 86 void Daire::kurYcap( double r ) 87 { ycap = ( r >= 0? r : 0 ); } 88 KALITSALLIK Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 10

89 // Dairenin yarıçapını al 90 double Daire::alYcap() const { return ycap; } 91 92 // Dairenin alanını hesapla 93 double Daire::alan() const 94 { return 3.14159 * ycap * ycap; } 95 96 // Dairenin alanı : 97 // Merkez = [x, y]; Yarıçap = #.## 98 ostream &operator<<( ostream &output, const Daire &c ) 99 { 100 output << Merkez = " << static_cast< Nokta >( c ) 101 << "; Yarıçap = " 102 << setiosflags( ios::fixed ios::showpoint ) 103 << setprecision( 2 ) << c.ycap; 104 105 return output; 106 } 107 // Fig. 19.4: fig19_04.cpp 108 // baz-class pointerı derived-class pointer-a çevir 109 #include <iostream> 110 111 using std::cout; 112 using std::endl; 113 114 #include <iomanip> 115 116 #include nokta.h" 117 #include daire.h" 118 119 int main() 120 { KALITSALLIK 1. 1 Fonksiyon tanımları ---------------------- Sürücü 1. header-ları yükle 1.1 nesneleri belirle Nuri 121ÖZALP (ANKARA Nokta ÜNİVERSİTESİ) *noktaptr İLERİ PROGRAMLAMA = 0, p( 30, 50 ); 11

122 Daire *daireptr = 0, c( 2.7, 120, 89 ); 123 124 cout << Nokta p: " << p << "\ndaire c: " << c << '\n'; 125 1.1 NEsneleri belirle 126 // Daireyi nokta gibi işler (baz sınıfı kısmına bak) 127 noktaptr = &c; // Dairenin adresini noktaptr ye aktar 1.2 Nesneleri ata 128 cout << "\ndaire c ( *noktaptr ile): " 2. Fonksiyon çağır 129 << *noktaptr << '\n'; 130 131 // Daireyi daire gibi işle 132 // baz-class pointerı derived-class pointera çevir 133 DairePtr = static_cast< Daire * >( noktaptr ); 134 cout << "\ndaire c (*daireptr ile):\n" << *daireptr 135 << "\n c nin alanı ( daireptr ile): " 136 << daireptr->alan() << '\n'; 137 138 // TEHLİKELİ: Noktayi Daire gibi işle 139 noktaptr = &p; 140 141 // baz-class pointerı derived-class pointera çevir 142 daireptr = static_cast< Daire * >( noktaptr ); 143 cout << "\nnokta p (*daireptr ile):\n" << *daireptr 144 << "\n daireptr nesnesinin alanı : " 145 << daireptr->alan() << ı işaret eder << endl; 146 return 0; 147 } KALITSALLIK Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 12

19.4 Baz-Sınıfı Üyelerden Türev Sınıfı Yapma Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 13 Nokta p: [30, 50] Daire c: Merkez = [120, 89]; Yarıçap = 2.70 Daire c ( *noktaptr ile): [120, 89] Daire c ( *daireptr ile): Merkez = [120, 89]; Yarıçap= 2.70 C nin alanı ( daireptr ile): 22.90 Nokta p ( *daireptr ile): Merkez = [30, 50]; Yarıçap= 0.00 daireptr nesnesinin alanı : 0.00 ı işaret eder

19.5 Üye Fonksiyon Kullanımı Türev Sınıfı Baz sınıfın private üyelerine doğrudan erişim sağlayamaz private üyeleri gizlemede, sistemleri test etme, düzenleme ve yenilemede oldukça yardımcıdır. 19.6 Baz-Sınıfı Üyeleri Türev Sınıfına Yükleme baz-sınıfı üye fonksiyon yüklemesi Türev sınıfında, o fonksiyonun yeni versiyonunu al Aynı fonksiyon adı, farklı tanım Baz sınıfı versiyonuna türev sınıfından ulaşmak için hedef-çözünürlük operatörü kullanılabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 14

19.6 Baz-Sınıfı Üyeleri Türev Sınıfına Yükleme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 15 // Fig. 19.5: isci.h // İşci sınıfı tanımları #ifndef ISCI_H #define ISCI_H class Isci { public: Isci( const char *, const char * ); // constructor void yaz() const; // İlk ve soyadı yaz ~Isci(); // destructor private: char *ilkad; // dinamik düzenlenen string char *soyad; // dinamik düzenlenen string }; #endif // Fig. 19.5: isci.cpp // Isci için üye fonksiyonlar #include <iostream> using std::cout; #include <cstring> #include <cassert> #include "isci.h" // Constructor ilk ve soyad için dinamik düzenlemeli yer ayırır // ve ilk ve soyadı nesneye kopyalamak için strcpy // kullanır Isci::Isci( const char *ilk, const char *soy) { ilkad= new char[ strlen( ilk) + 1 ]; assert( ilkad!= 0 ); // yer yok ise dur strcpy( ilkad, ilk); 1. İsci class tanımı ----------------------- 1. Header yükle 1.1 Fonksiyon tanımları

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 16 19.6 Baz-Sınıfı Üyeleri Türev Sınıfına Yükleme soyad= new char[ strlen( soy) + 1 ]; assert( soyad!= 0 ); // yer yok ise dur strcpy( soyad, soy); } void Isci::yaz() const { cout << ilkad << ' ' << soyad; } // Destructor dinamik düzenlemeyi kaldırır Isci::~Isci() { delete [] ilkad; // dinamik belleği düzenle delete [] soyad; } // Fig. 19.5: saatlik.h // SaatlikIsci classı #ifndef SAATLIK_H #define SAATLIK_H #include "isci.h" class SaatlikIsci : public Isci { public: SaatlikIsci( const char*, const char*, double, double ); double odeme() const; // maaşı hesapla ve gönder void yaz() const; // önemsiz baz-class yaz fonksiyonu private: saati }; double ucret; double saat; #endif // saatlik ücret // haftalık çalışma 1.1 Fonksiyon tanımları --------------------- 1. SaatlikIsci class tanımı

19.6 Baz-Sınıfı Üyeleri Türev Sınıfına Yükleme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 17 // Fig. 19.5: saatlik.cpp // SaatlikIsci için üye fonksiyonlar #include <iostream> using std::cout; using std::endl; #include <iomanip> using std::ios; using std::setiosflags; using std::setprecision; #include "saatlik.h" // Constructor SaatlikIsci::SaatlikIsci( const char *ilk, const char *soy, double ilksaat, double ilkucret) : Isci( ilk, soy) // baz-class constructor-ı çağır { saat = ilksaat; // geçerli olmalı ucret = ilkucret; // geçerli olmalı } // Odemeyi al double SaatlikIsci::odeme() const { return ucret * saat; } 1. Header yükle 1.1 fonksiyon tanımları

19.6 Baz-Sınıfı Üyeleri Türev Sınıfına Yükleme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 18 // Ad ve ödemeyi yaz void SaatlikIsci::yaz() const { cout << "SaatlikIsci::yaz() çalışıyor\n\n"; Isci::yaz(); // baz-class yaz fonksiyonunu çağır } cout << " saatlik işçi olup odenecek $" << setiosflags( ios::fixed ios::showpoint ) << setprecision( 2 ) << odeme() << endl; // Fig. 19.5: fig.19_05.cpp // sürücü sınıfındaki bir baz-class üye fonksiyonunu // atlama #include "saatlik.h" int main() { SaatlikIsci s( "Ali", "Çalışkan", 40.0, 10.00 ); s.yaz(); return 0; } 1.1 fonksiyon tanımları -------------------- 1. Header yükle 1.1 nesne değerlerini gir 2. Fonksiyon çağır SaatlikIsci::yaz() çalışıyor Ali Çalışkan saatlik işçi olup ödenecek $400.00

19.7 public, private, ve protected Kalıt Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 19 public Baz sınıfı üye erişim belirteci Kalıt tipi public kalıt Türev sınıfında public. Herhangi staticolmayan üye fonksiyon, friend fonksiyon ve üye-olmayan fonksiyon ile doğrudan erişilebilir, protected kalıt Türev sınıfında protected static-olmayan üye fonksiyonlar, ve friend fonksiyon ile erişilebilir private kalıt Türev sınıfında private static-olmayan üye fonksiyon ve friend fonksiyon ile erişilebilir Türev sınıfında protected Türev sınıfında protected Türev sınıfında private protected static-olmayan üye fonksiyon ve friend fonksiyon ile erişilebilir static-olmayan üye fonksiyon ve friend fonksiyon ile erişilebilir static-olmayan üye fonksiyon ve friend fonksiyon ile erişilebilir Türev sınıfında saklı. Tüev sınıfında saklı. Türev sınıfında saklı. private Baz sınıfının public veya protected üyeleri üzerinden staticolmayan üye fonksiyon ve friend fonksiyon ile erişilebilir Baz sınıfının public veya protected üyeleri üzerinden staticolmayan üye fonksiyon ve friend fonksiyon ile erişilebilir Baz sınıfının public veya protected üyeleri üzerinden staticolmayan üye fonksiyon ve friend fonksiyon ile erişilebilir.

19.8 Doğrudan ve Dolaylı Baz-Sınıfları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 20 Doğrudan baz sınıfı Türev sınıfı tanımlandığında, (:) notasyonu ile o türev sınıfı header- ında açık olarak listelenir class : public Isci Isci, SaatlikIsci nin doğrudan baz sınıfıdır Dolaylı Baz sınıfı Class hiyerarşisinin iki veya daha üst düzeyinden kalıttır class DakikaIsci: public SaatlikIsci Isci, DakikaIsci nin dolaylı baz sınıfıdır

19.9 Türev Sınıfında Constructor ve Destructor Kullanımı Baz class başlatıcısı Üye başlatıcı sintaksı kullanır Baz-sınıfı oluşturucusunu doğrudan çağırmak için türev sınıfı oluşturucuda verilebilir Aksi halde baz sınıfı default oluşturucusu kapalı olarak çağrılır Baz-sınıfı oluşturucusu ve baz-sınıfı atama operatörleri türev sınıfından kalıt değildir Fakat, türev sınıfı oluşturucuları ve atama operatörleri onları çağırabilir Türev sınıfı oluşturucusu Baz sınıfı üyelerini atamak için ilk önce baz sınıfı için oluşturucuyu çağırır Eğer türev sınıfı oluşturucusu gözardı edilirse, onun default oluşturucusu baz-sınıfı default oluşturucuyu çağırır Yokediciler, oluşturucuların tam zıt sırası ile çağrılır Türev sınıfı yokedicisi, baz sınıfı yokedicisinden önce çağrılır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 21

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 22 // Fig. 19.7: nokta2.h // Nokta sınıfı tanımı #ifndef NOKTA2_H #define NOKTA2_H class Nokta { public: Nokta( int = 0, int = 0 ); // default constructor ~Nokta(); // destructor protected: // sürücü sınıfları erişebilir int x, y; // Noktanın x ve y koordinatları }; #endif // Fig. 19.7: nokta2.cpp // Nokta için üye fonksiyonlar #include <iostream> using std::cout; using std::endl; #include "nokta2.h" // Constructor Nokta::Nokta( int a, int b ) { x = a; y = b; } cout << "Nokta constructor: " << '[' << x << ", " << y << ']' << endl;

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 23 // Destructor Nokta::~Nokta() { cout << "Nokta destructor: " << '[' << x << ", " << y << ']' << endl; } // Fig. 19.7: daire2.h // Daire tanımı #ifndef DAIRE2_H #define DAIRE2_H #include "nokta2.h" class Daire: public Nokta { public: // default constructor Daire( double r = 0.0, int x = 0, int y = 0 ); ~Daire(); private: double ycap; }; #endif

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 24 // Fig. 19.7: daire2.cpp // Daire için üye fonksiyonlar #include <iostream> using std::cout; using std::endl; #include "daire2.h" // Daire Constructor-ı Nokta constructor-ını çağırır Daire::Daire( double r, int a, int b ) : Nokta( a, b ) // baz-class constructor-ı çağır { ycap = r; cout << "Daire constructorı: Yarıçap = " << ycap << " [" << x << ", " << y << ']' << endl; } // Destructor Daire::~Daire() { cout << "Daire destructor: Yarıçap = " << ycap << " [" << x << ", " << y << ']' << endl; }

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 25 // Fig. 19.7: fig19_07.cpp // Demonstrate when baz-class ve sürücü-class // constructor-lar ve destructor-lar çağrıldığında #include <iostream> using std::cout; using std::endl; #include "nokta2.h" #include "daire2.h" int main() { // Nokta için constructor ve destructor çağrımını göster { Nokta p( 11, 22 ); } // blok sonu } cout << endl; Daire daire1( 4.5, 72, 29 ); cout << endl; Daire daire2( 10, 5, 5 ); cout << endl; return 0;

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 26 Daire constructorı: [11, 22] Nokta destructorı: [11, 22] Nokta constructorı: [72, 29] Daire constructorı: radius is 4.5 [72, 29] Nokta constructorı: [5, 5] Daire constructorı: radius is 10 [5, 5] Daire destructorı: radius is 10 [5, 5] Nokta destructorı: [5, 5] Daire destructorı: radius is 4.5 [72, 29] Nokta destructorı: [72, 29]

19.10 Kapalı Türev-Sınıfı Nesneleri Baz-Sınıfı Nesnelere Dönüştürme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 27 bazsınıfınesne = turevsınıfınesne; Çalışır Türev sınıfı nesnelerin baz sınıf nesnelerden daha fazla üyeye sahip olduğunu hatırlayınız Baz sınıfına ilave data verilmez turevsınıfınesnesi = bazsınıfınesnesi; Düzgün çalışmayabilir Bir atama operatörü türev sınıfında yüklenmedikçe, türev sınıfındaki fazla veri üyeleri atanamayacaktır Baz sınıfı, türev sınıfından daha az veri üyesine sahiptir Bazı veri üyeleri türev sınıfı nesnesinde kaybolur

19.10 Kapalı Türev-Sınıfı Nesneleri Baz-Sınıfı Nesnelere Dönüştürme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 28 Baz ve Türev sınıfı pointer ve nesneleri birleştirmenin dört yolu Bir baz-sınıfı nesneyi bir baz sınıfı pointer ile refere etme İzin verilir Bir türev sınıfı nesneyi bir türev sınıfı pointer ile refere etme İzin verilir Bir türev sınıfı nesneyi bir baz sınıfı pointer ile refere etme. Muhtemelen sintaks hatası Kod sadece baz sınıf üyeyi refere edebilir, veya sintaks hatası Bir baz sınıfı nesneyi bir türev sınıfı pointer ile refere etme Sintaks hatası Türev sınıfı pointer önce bir baz sınıfı pointer-a atanmalıdır

19.11 Kalıt ile Yazılım Mühendisliği Sınıflar çoğu zaman yakın ilişkilidir Ortak atama ve davranışları sadeleştir ve bunları bir baz sınıfına yerleştir Türev sınıflarını oluşturmak için kalıt kullan Baz sınıfında düzenlemeler public ve protected arayüzler aynı oldukça türev sınıfları değişmez Türev sınıfları yeniden derlenmek zorunda kalabilir Kalıt bir ilişkidir 9.12 Kompozisyon ve Kalıt Kompozisyon bir başka sınıftan bir veri üyesi olarak bir nesneye sahip sınıf bir ilişkiye sahiptir" Isci bir DogumGunu; //Yanlış! Isci sahiptir DogumGunu;//Kompozisyon Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 29

9.13 İlişkileri Kullan ve Bil İlişki kullan Bir nesne bir başka nesnenin bir üye fonksiyonuna bir fonksiyon çağrımı gerçekleştirir İlişki bil Bir nesne bir başkasının farkındadır Bir başka nesneye pointer veya bağlayıcı içerir Bir birlik olarak da adlandırılır 9.14 Örnek: Nokta, Daire, Silindir Nokta sınıfı tanımla Daire sürücüsü oluştur Silindir sürücüsü oluştur Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 30

9.14 Örnek: Nokta, Daire, Silindir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 31 // Fig. 19.8: nokta2.h // class tanımı #ifndef NOKTA2_H #define NOKTA2_H #include <iostream> using std::ostream; class Nokta { friend ostream &operator<<( ostream &, const Nokta & ); public: Nokta ( int = 0, int = 0 ); // default constructor void kurnokta( int, int ); // koordinatları kur int alx() const { return x; } // x koordinatını al int aly() const { return y; } // y koordinatını al protected: // sürücü sınıfları erişebilir int x, y; // nokta koordinatları }; #endif

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 32 // Fig. 19.8: nokta2.cpp // Üye fonksiyonlar #include "nokta2.h" // Constructor Nokta::Nokta( int a, int b ) { kurnokta( a, b ); } void Nokta::kurNokta( int a, int b ) { x = a; y = b; } // Çıktı ostream &operator<<( ostream &cikti, const Nokta &p ) { cikti << '[' << p.x << ", " << p.y << ']'; return cikti; } // << sonu

// Fig. 19.9: daire2.h // #ifndef DAIRE2_H #define DAIRE2_H #include <iostream> using std::ostream; #include "nokta2.h" class Daire: public Nokta { friend ostream &operator<<( ostream &, const Daire & ); public: // default constructor Daire( double r = 0.0, int x = 0, int y = 0 ); void kurycap( double ); double alycap() const; double alan() const; protected: double ycap; }; #endif // Fig. 19.9: daire2.cpp // Üye fonksiyonlar #include <iomanip> using std::ios; using std::setiosflags; using std::setprecision; Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 33

#include "daire2.h" // Daire Constructorı bir üye belirteci ile Nokta constructorını çağırır // ve ycap ilk değerini atar Daire::Daire( double r, int a, int b ) : Nokta ( a, b ) // baz-class constructorı çağır { kurycap( r ); } void Daire::kurycap( double r ) { ycap= ( r >= 0? r : 0 ); } double Daire::alycap() const { return ycap; } // Alanı hesapla double Daire::alan() const { return 3.14159 * ycap* ycap; } // Çıktı ostream &operator<<( ostream &cikti, const Daire &c ) { cikti << "Merkez= " << static_cast< Nokta > ( c ) << "; Yarıçap = " << setiosflags( ios::fixed ios::showpoint ) << setprecision( 2 ) << c.ycap; return cikti; } // << sonu KALITSALLIK Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 34

// Fig. 19.10: silindir2.h #ifndef SILINDIR2_H #define SILINDIR2_H #include <iostream> using std::ostream; #include "daire2.h" class Silindir : public Daire{ friend ostream &operator<<( ostream &, const Silindir & ); public: // default constructor Silindir( double h = 0.0, double r = 0.0, int x = 0, int y = 0 ); void kuryuk( double ); double alyuk() const; double alan() const; double hacim() const; protected: double yuk; }; // yüksekliği kur // return yükseklik // Silindirin yüksekliği #endif Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 35

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 36 // Fig. 19.10: silindir2.cpp #include "silindir2.h" // Silindir constructor Daire constructorı çağırır Silindir::Silindir( double h, double r, int x, int y ) : Daire( r, x, y ) // baz-class constructorı çağır { kuryuk( h ); } void Silindir::kurYuk( double h ) { yuk= ( h >= 0? h : 0 ); } double Silindir::alYuk() const { return yuk; } // yüzey alanı double Silindir::alan() const { return 2 * Daire::alan() + 2 * 3.14159 * ycap* yuk; } // Hacim double Silindir::hacim() const { return Daire::alan() * yuk; } // Silindir boyutlarının çıktısı ostream &operator<<( ostream &cikti, const Silindir &c ) { cikti << static_cast< Daire >( c ) << "; Yükseklik = " << c.yuk; } return cikti;

// Fig. 19.10: fig19_10.cpp // Silindir sınıfı için türev #include <iostream> Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 37 using std::cout; using std::endl; #include "nokta2.h" #include "daire2.h" #include "silindir2.h" int main() { // Silindir nesnesi yarat Silindir sil( 5.7, 2.5, 12, 23 ); cout << "X koordinatı:" << sil.alx() << "\ny koordinatı:" << sil.aly() << "\nyarıçap:" << sil.alycap() << "\nyükseklik: " << sil.alyuk() << "\n\n"; // Değerleri değiştir sil.kuryuk( 10 ); sil.kurycap( 4.25 ); sil.kurnokta( 2, 2 ); cout << "Silindirin yeni yüksekliği yarıçapı ve yeri:\n" << sil<< '\n';

cout << "Yüzey Alanı:\n" << sil.alan() << '\n'; Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA KALITSALLIK 38 // Silindiri nokta olarak göster Nokta &pref = sil; // pref onun bir nokta olduğunu "düşünür" cout << "\nnokta olarak yazılan silindir: " << pref << "\n\n"; // Silindiri Daire olarak göster Daire &daireref = sil; // daireref onu bir daire gibi görür cout << "Daire olarak yazılan silindir:\n" << daireref << "\nalan: " << daireref.alan() << endl; } return 0; X koordinatı: 12 Y koordinatı: 23 yarıçap: 2.5 Yükseklik: 5.7 Silindirin yeni yüksekliği yarıçapı ve yeri: Merkez = [2, 2]; Yarıçap = 4.25; Yükseklik = 10.00 Silindirin alanı: 380.53 Nokta olarak yazılan silindir: [2, 2] Daire olarak yazılan silindir: Merkez= [2, 2]; Yarıçap= 4.25 Alan: 56.74

Bölüm 20- Virtual(Sanal) Fonksiyonlar ve Polimorfizm Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 1 İçerik 20.1 Giriş 20.2 Tip Alanları ve switch Deyimleri 20.3 Virtual Fonksiyonlar 20.4 Soyut Baz Sınıfları ve Somut Sınıflar 20.5 Polimorfizm 20.6 Örnek: Polimorfizm ile Ödeme Sistemi 20.7 Yeni Sınıflar ve Dİnamik Birleştirme 20.8 Virtual Yokediciler 20.9 Örnek: Kalıtsal Arayüz ve Uygulamalar 20.10 Polimorfizm, virtual Fonksiyonlar ve Dinamik Birleştirme

20.1 Giriş Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 2 virtual fonksiyonlar ve Polimorfizm Kolaylıkla genişletilebilir sistemler tasarla ve uygula Programlar, bir hiyerarşi içindeki tüm varolan sınıfları genel anlamda işlemek için yazılabilir

20.2 Tip Alanları ve switch Deyimleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 3 switch deyimi Nesnenin tipine göre hareket et Bir switch yapısı,, sekiller hiyerarşisindeki tipe göre hangi yaz fonksiyonunu kullanacağını belirleyeyebilir switch ile ilgili sorunlar Programcı bir switch deki tüm olası durumları test etmeyi unutabilir Bunu takip etmek zaman alıcı ve hata yapmaya açıktır virtual fonksiyonlar ve polimorfik programlama switch gereksinimini ortadan kaldırabillir

virtual fonksiyonlar 20.3 Sanal(Virtual) Fonksiyonlar switch deyimleri yerine kullan Deklarasyon: Baz sınıfındaki prototip fonksiyonun önünde virtual yaz virtual void ciz() const; Bir sürücü sınıfı nesneye baz sınıfı pointer doğru çiz fonksiyonunu çağıracaktır Eğer sürücü sınıfında bir virtual fonksiyon tanımlamamışsa baz sınıfından kalıt alınır SekilPtr->Ciz(); Derleyici dinamik birleştirme uygular Fonksiyon, çalışma (execution) anında belirlenir SekilNesne.Ciz(); Derleyici statik birleştirme uygular Fonksiyon, derleme(compiling) anında belirlenir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 4

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 5 20.4 Soyut ve Somut Sınıflar Soyut sınıflar Temel amacı, diğer sınıflar için bir baz sınıfı sağlamaktır Soyut baz sınıfının hiç bir nesnesi sabitlenemez Real nesne tanımlamak için çok genel; örneğin, IkiBoyutluSekil Pointer ve referansa sahip olabilir Somut sınıflar Nesneleri sabitlenebilir Reel nesneler için özel tanım sağlar; örneğin, Kare, Daire Soyut sınıf yapma Sınıfın bir veya daha çok virtual fonksiyonunu soyut olarak (başlangış değerini sıfır alarak) tanımla virtual double kazanclar() const = 0; Soyut virtual fonksiyon

20.5 Polimorfizm Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 6 Polimorfizm: Farklı sınıflardan nesnelerin (kalıtsallıklarına bağlı olarak) aynı fonksiyon çağrımlarına farklı yanıt verme yeteneği Baz-sınıfı pointer (veya referans) bir virtual fonksiyon çağırır C++ nesnedeki doğru çoklu - yüklü fonksiyonu seçer yaz bir virtual fonksiyon olmasın. Bu durumda Isci e, *eptr = &e; SaatlikIsci h, *hptr = &h; eptr->yaz(); //baz(isci)-sınıfı yaz fonksiyonunu çağırır hptr->yaz(); // türev(saatlikisci)-sınıfı yaz fonksiyonunu çağırır eptr=&h; //izin verilebilir kapalı dönüşüm eptr->yaz(); // yine baz(isci)-sınıfı yaz fonksiyonunu çağırır

20.6 Yeni Sınıflar ve Dinamik Birleştirme Dinamik Birleştirme (sonradan birleştirme) virtual fonksiyonları derlerken nesne tipine gereksinim yok Derlemeden sonra oluşturulan yeni sınıflara yer açar Kaynak kodu müşterilerine vermek istemeyen bağımsız yazılımcılar için önemli Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 7

20.7 Virtual Yokediciler Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 8 Problem: Eğer (virtual olmayan yokedicili) türev nesnesi baz sınıfı pointer-a uygulanan delete operatörü ile yokedilirse, (o türev nesnesininki yerine) nesnedeki baz sınıfı yokedicisi çağrılır Çözüm: virtual baz sınıfı yokedicisi tanımla Bu durumda uygun yokedici çağrılır 20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nokta, Daire, Silindir hiyerarşisini tekrar inceleme Hiyerarşinin başında Soyut baz sınıfı Sekil kullanılacak

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 9 // Fig. 20.1: sekil.h // soyut baz classı Sekil #ifndef SEKIL_H #define SEKIL_H class Sekil { public: virtual double alan() const { return 0.0; } virtual double hacim() const { return 0.0; } }; // saf virtual fonksiyonlar sürücü sınıflarında atılır virtual void yazsekilad() const = 0; virtual void yaz() const = 0; #endif 1. Sekil Tanımı (soyut baz sınıfı) --------------------- 1. Nokta tanımı (türev sınıfı) // Fig. 20.1: nokta1.h #ifndef NOKTA1_H #define NOKTA1_H #include <iostream> using std::cout; #include "sekil.h" class Nokta: public Sekil{ public: Nokta( int = 0, int = 0 ); // default constructor void kurnokta( int, int ); int alx() const return x; int aly() const { return y; }

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 10 virtual void yazsekilad() const { cout << "Nokta: "; } virtual void yaz() const; private: int x, y; }; #endif 1. Nokta tanımı (türev sınıfı) 1.1 Fonksiyon tanımları // Fig. 20.1: nokta1.cpp #include "nokta1.h" Nokta::Nokta( int a, int b ) { kurnokta( a, b ); } void Nokta::kurNokta( int a, int b ) { x = a; y = b; } void Nokta::yaz() const { cout << '[' << x << ", " << y << ']'; }

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 11 // Fig. 20.1: daire1.h #ifndef DAIRE1_H #define DAIRE1_H #include "nokta1.h" 1. Daire tanımı (türev sınıfı) class Daire: public Nokta { public: // default constructor Daire( double r = 0.0, int x = 0, int y = 0 ); void kurycap( double ); double alycap() const; virtual double alan() const; virtual void yazsekilad() const { cout << "Daire: "; } virtual void yaz() const; private: double ycap; }; #endif

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 12 // Fig. 20.1: daire1.cpp #include <iostream> using std::cout; #include "daire1.h" Daire::Daire( double r, int a, int b ) : Nokta( a, b ) { kurycap( r ); } void Daire::kurycap( double r ) { ycap= r > 0? r : 0; } double Daire::alycap() const { return ycap; } double Daire::alan() const { return 3.14159 * ycap* ycap; } void Daire::yaz() const { Nokta::yaz(); cout << "; Yarıçap= " << ycap; }

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 13 // Fig. 20.1: silindir1.h #ifndef SILINDIR1_H #define SILINDIR1_H #include "daire1.h" class Silindir: public Daire { public: // default constructor Silindir( double h = 0.0, double r = 0.0, int x = 0, int y = 0 ); void kuryuk( double ); double alyuk(); virtual double alan() const; virtual double hacim() const; virtual void yazsekilad() const {cout << "Silindir: ";} virtual void yaz() const; private: double yuk; }; #endif 1. Silindir tanımı (türev sınıfı)

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 14 // Fig. 20.1: silindir1.cpp // Silindir için Üye ve friend fonksiyon tanımları #include <iostream> using std::cout; #include "silindir1.h" Silindir::Silindir( double h, double r, int x, int y ) : Daire( r, x, y ) { kuryuk( h ); } void Silindir::kurYuk( double h ) { yuk = h > 0? h : 0; } double Silindir::alYuk() { return yuk; } double Silindir::alan() const { // yüzey alanı return 2 * Daire::alan() + 2 * 3.14159 * alycap() * yuk; } double Silindir::hacim() const { return Daire::alan() * yuk; } void Silindir::yaz() const { Daire::yaz(); cout << "; Yükseklik= " << yuk; }

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 15 // Fig. 20.1: fig20_01.cpp // Şekil nokta daire ve silindir hiyerarşisi için sürücü #include <iostream> using std::cout; using std::endl; #include <iomanip> using std::ios; using std::setiosflags; using std::setprecision; #include "sekil.h" #include "nokta1.h" #include "daire1.h" #include "silindir1.h" void PointerileSanal( const Sekil * ); void RefileSanal( const Sekil & ); int main() {

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 16 cout << setiosflags( ios::fixed ios::showpoint ) << setprecision( 2 ); Nokta nokta( 7, 11 ); // nokta yarat Daire daire( 3.5, 22, 8 ); Silindir silindir( 10, 3.3, 10, 10 ); nokta.yazsekilad(); nokta.yaz(); cout << '\n'; // static bağlama // static bağlama daire.yazsekilad(); daire.yaz(); cout << '\n'; // static bağlama // static bağlama silindir.yazsekilad(); // static bağlama silindir.yaz(); // static bağlama cout << "\n\n"; Sekil *sekillerindizisi[ 3 ]; // baz-class pointer dizisi sekillerindizisi[ 0 ] = &nokta; sekillerindizisi[ 1 ] = &daire; sekillerindizisi[ 2 ] = &silindir; // sekillerindizisi ni tara ve PointerIleSanal ı çağırarak // dinamik bağlama kullanarak herbir nesnenin şekil adını // durumunu, alanını, ve hacmini yaz

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 17 cout << "Baz-class pointerlar ile " << "sanal(virtual) fonksiyon çağrımı\n"; for ( int i = 0; i < 3; i++ ) PointerileSanal( sekillerindizisi[ i ] ); cout << "Baz-class referanslar ile" << "sanal fonksiyon çağrımı\n"; for ( int j = 0; j < 3; j++ ) RefileSanal( *sekillerindizisi[ j ] ); return 0; } // baz-class pointer ile dinamik bağlama void PointerileSanal( const Sekil *bazclassptr ) { bazclassptr->yazsekilad(); bazclassptr->yaz(); cout << "\nalan = " << bazclassptr->alan() << "\nhacim= " << bazclassptr->hacim() << "\n\n"; } // fonks sonu // baz-class referans ile dinamik bağlama void RefileSanal( const Sekil &bazclassref ) { bazclassref.yazsekilad(); bazclassref.yaz(); cout << "\nalan= " << bazclassref.alan() << "\nhacim= " << bazclassref.hacim() << "\n\n"; } // fonks sonu

20.8 Örnek: Kalıtsal Arayüz ve Uygulama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 18 Nokta: [7, 11] Daire: [22, 8]; Yarıçap= 3.50 Silindir: [10, 10]; Yarıçap= 3.30; Yükseklik= 10.00 Baz-class pointerlar ile sanal(virtual) fonksiyon çağrımı Nokta: [7, 11] Alan = 0.00 Hacim = 0.00 Daire: [22, 8]; Yarıçap= 3.50 Alan= 38.48 Hacim = 0.00 Silindir: [10, 10]; Yarıçap= 3.30; Yükseklik= 10.00 Alan= 275.77 Hacim = 342.12 Baz-class referanslar ile sanal fonksiyon çağrımı Nokta: [7, 11] Alan = 0.00 Hacim = 0.00 Daire: [22, 8]; Yarıçap= 3.50 Alan= 38.48 Hacim = 0.00 Silindir: [10, 10]; Yarıçap= 3.30; Yükseklik= 10.00 Alan= 275.77 Hacim = 342.12

20.9 Polimorfizm, virtual Fonksiyonlar ve Dinamik Birleştirme Polimorfizm ne zaman kullanılır Az bellek kullanımı ve hızlı çalışma zamanı gerekli ise Performansı artırmak için STL (Standard Template Library) de kullanılmamalı virtual fonksiyon tablosu (vtable) virtual fonksiyonlu her sınıf bir vtable- a sahiptir Her virtual fonksiyon için, vtable uygun fonksiyona bir pointer-a sahiptir Türev sınıfı baz sınıfı olarak aynı fonksiyona sahipse, bu durumda fonksiyon pointer-ı baz fonksiyonunu işaret eder Detaylı açıklama aşağıdadır: Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 19

20.9 Polimorfizm, virtual Fonksiyonlar ve Dinamik Birleştirme Sekil vtable 0.0 a 0.0 h 0 ysa Nokta nokta 0 yz a h Nokta vtable x= 7 y = 11 nokta [ x, y] 2 r daire ysa yz a h ysa yz Daire vtable 5 4 3 Offset 8 byte Daire daire x= 22 y = 8 yarıçap =3.5 [ 1 ] [ 2 ] [ 3 ] SekillerDizisi &nokta &daire &silindir [ x, y]r Silindir silindir 1 2 2 r 2 2 r h silindir rh [ x,y]rh a h ysa yz Silindir vtable x= 22 y = 8 yarıçap =3.5 yüksek =10 2 BazClassPtr Sanal fonksiyon çağrımı akışı BazClasssPtr ->yazsekiladi( ); koyu oklarla gösterilmiştir 1 &daire yi bazclassptr ye aktar a = alan fonksiyonu h = hacim fonksiyonu 2 daire nesnesini al 3 daire vtable ını al ysa = yazsekiladi fonksiyonu yz = yaz fonksiyonu 4 vtable daki yazsekiladi pointer-ını al 0 giriş somut virtual fonksiyonu anlamında 5 yazsekiladi nı Daire için çalıştır x= yaricap ; h = yuksek Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA SANAL FONKSİYONKAR-POLİMORFİZM 20

Bölüm 21 - C++ Stream Input/Output Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 1 İçerik 21.1 Giriş 21.2 Akış(Stream)lar 21.2.1 iostream Library Header Dosyaları 21.2.2 Stream Input/Output Sınıfları ve Nesneleri 21.3 Stream Output 21.3.1 Stream-Insertion Operatörü 21.3.2 Taşırma Stream-Insertion/Extraction Operatorleri 21.3.3 char * Değişkenleri Çıktısı 21.3.4 put Stream Üye Fonksiyonu ile Karakter Çıktısı 21.4 Stream Input 21.4.1 Stream-Extraction Operatörü 21.4.2 get ve getline Üye Fonksiyonları 21.4.3 istream Üye Fonksiyonları peek, putback ve ignore 21.4.4 Type-Safe I/O 21.5 read, gcount ve write ile Formatsız I/O

Bölüm 21 - C++ Stream Input/Output Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 2 İçerik (devam) 21.6 Stream Manipulatörleri(Düzenleyicileri) 21.6.1 Integral Stream Bazı: dec, oct, hex ve setbase 21.6.2 Floating-Point Duyarlılık (precision, setprecision) 21.6.3 Alan Uzunluğu(Field Width) (setw, width) 21.6.4 Kullanıcı Tanımlı Manipulatörler 21.7 Stream Format Durumları 21.7.1 Format Durum Bayrakları 21.7.2 Uç sıfırlar ve Desimal noktalar (ios::showpoint) 21.7.3 Sağlama (ios::left, ios::right, ios::internal) 21.7.4 Tamponlama (fill, setfill) 21.7.5 Integral Stream Bazı (ios::dec, ios::oct, ios::hex, ios::showbase) 21.7.6 Floating-Point Sayılar; Bilimsel Gösterim (ios::scientific, ios::fixed) 21.7.7 Uppercase/Lowercase Kontrol (ios::uppercase) 21.7.8 Format bayraklarını kurma ve yenileme(flags, setiosflags, resetiosflags) 21.8 Stream Hata Durumları 21.9 Output Stream-i Input Stream-e bağlama

21.1 Giriş Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 3 Çoğu C++ I/O özellikleri nesne tabanlıdır Referansları, fonksiyon ve operatör yüklemeleri kullan C++ tip korumalı I/O kullanır Her I/O operasyonu veri tipine duyarlı olacak şekilde gerçekleşir Genişlik Kullanıcı standart tiplerin yanısıra kullanıcı tanımlı I/O tipi belirleyebilir

21.2 Akış(Stream)lar Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 4 Stream (Akış) Bir Byte-lar dizisi formunda bilgi transferi I/O Operasyonları: Input: Bir girdi aygıtından (klavye, disk sürücü, network bağlantısı gibi) ana belleğe geçen bir stream Output: Ana bellekten bir çıktı aygıtına (ekran, yazıcı, disk sürücü, network bağlantısı gibi) geçen bir stream

21.2 Akış(Stream)lar I/O operasyonları bir darboğazdır Bir stream-in akış zamanı, stream-deki verinin CPU tarafından işlenme zamanından çok daha fazladır Alt-düzey I/O Formatsız İlgiye göre keyfi byte birimi Yüksek hız, yüksek hacim fakat uygun/kullanışlı değil Yüksek-düzey I/O Formatlı Byte-lar anlamlı birimlere bölünür : tamsayılar, karakterler v.s. Yüksek hacimli dosya işleme hariç tüm I/O için iyi. Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 5

21.2.1 iostream Library Header Dosyaları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 6 iostream kütüphanesi: <iostream.h>: cin, cout, cerr, ve clog nesnelerini içerir <iomanip.h>: parameteleştirilmiş stream düzenleyicilerini içerir <fstream.h>: kullanıcı kontrollü dosya işleme operasyonlarında önemli olan bilgileri içerir

21.2.2 Stream Input/Output Sınıfları ve Nesneleri ios: istream ve ostream ios dan kalıttır iostream, istream ve ostream den kalıttır. << (sol-kaydırma operatörü) stream yerleştirme (insertion ) operatörü olarak yüklenir >> (sağ-kaydırma operatörü) stream çıkarma (extraction ) operatörü olarak yüklenir Her iki operatör de cin, cout, cerr, clog, ve kullanıcı-tanımlı stream nesneleri ile kullanılır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 7

21.2.2 Stream Input/Output Sınıfları ve Nesneleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 8 istream: input stream cin >> birdegisken; cin birdegisken e ne tip bir veri atanacağını bilir (birdegisken nin tipine göre). ostream: output stream cout << birdegisken; cout çıktı veri tipini bilir cerr << birstring; birstring i hemen yaz. clog << birstring; birstring i çıktı desteği dolduktan sonra yaz

21.3 Stream Output ostream: formatlı/formatsız çıktı uygular Karakterler için put ve formatlanmamış karakterler için write kullanır Sayı çıktıları: decimal, octal ve hexadecimal Reel sayılar için değişik duyarlılık Formatlı metin çıktısı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 9

21.3.1 Stream-Insertion Operatörü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 10 << hazır tipler için çıktı Kullanıcı tipli çıktı için de kullanılır cout << \n ; Yenisatır karakterini yazar cout << endl; endl stream düzenleyici yenisatır karakterini uygulayıp, çıktı desteğini boşaltır. cout << flush; flush çıktı desteğini boşaltır

21.3.2 Taşırma Stream-Insertion/Extraction Operatörleri Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 11 << : soldan sağa ilişkilendirme, sol operatör nesnesine (örneğin cout) referans gönderir Çoklu kullanıma (taşırmaya) izin: cout << C ye " << " göre " << " daha kolay?"; Parantez kullanın cout << "1 + 2 = " << (1 + 2); //doğru cout << "1 + 2 = " << 1 + 2; //yanlış

21.3.3 char * Değişkenleri Çıktısı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 12 << char * tipinde bir string değişkenini çıktı verir Aynı stringin ilk karakterinin adresini çıktı vermek için, değişken tipini void * yap

21.3.3 char * Değişkenleri Çıktısı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 13 1 // Fig. 21.8: fig21_08.cpp 2 // char* değişkenine yüklenen adresi yazma 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int main() 9 { 10 char *string = "test"; 11 12 cout << Stringin değeri: " << string 13 << "\n static_cast< void * >( string ) değeri: " 14 << static_cast< void * >( string ) << endl; 15 return 0; 16 } 1stringi gir 2. Stringi yaz 2.1 void * tipi ver 2.2 pointer değerini (stringin adresini) yaz Value of string is: test static_cast< void *>( string ) değeri: 146a020

21.3.4 put Stream Üye Fonksiyonu ile Karakter Çıktısı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 14 put üye fonksiyonu Belirlenmiş akışa bir karakter çıktısı cout.put( 'A'); Çağrılan nesneye referans gönderir, birleştirilebilir cout.put( 'A' ).put( '\n' ); Bir ASCII-değer ifadesiyle çağrılabilir cout.put( 65 ); A çıktısını verir

21.4 Stream Input >> (stream-extraction) Akış girdisi oluşturmak için kullanılır Normalde whitespace (boşluk, tab, yenisatır) karakterlerini göz ardı eder EOF gördüğünde sıfır(false) gönderir, aksi halde çağırdığı nesneye (örneğin cin) referans gönderir Birleşik girdiye izin verir cin >> x >> y; >> akışın bit durumunu kontrol eder yanlış tip veri girişi ise failbit kurar operasyon başarısız ise badbit kurar Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 15

21.4.1 Stream-Extraction Operatörü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 16 >> ve << bağıl olarak yüksek önceliğe sahiptir Koşullu ve aritmetik ifadeler parantez içinde olmalı Döngü kullanımının popüler yolu while (cin >> not) EOF görüldüğünde 0 (false) gönderir ve döngü sona erer

1 // Fig. 21.11: fig21_11.cpp 21.4.1 Stream-Extraction Operatörü 2 // Stream-extraction operatörü - EOF DURUMUNDA SIFIR GÖNDERİR 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 int main() 10 { 11 int not, enbuyuk = -1; 12 13 cout << Notu gir(bitirmek için EOF gir): "; 14 while ( cin >> not ) { 15 if ( not > enbuyuk ) 16 enbuyuk = not; 17 18 cout << Notu gir(bitirmek için EOF gir): "; 19 } 20 21 cout << "\n\nen büyük not: " << enbuyuk << endl; 22 return 0; 23 } 1. Initialize variables 2. Perform loop 3. Output Program Output Notu gir(bitirmek için EOF gir): 67 Notu gir(bitirmek için EOF gir): 87 Notu gir(bitirmek için EOF gir): 73 Notu gir(bitirmek için EOF gir): 95 Notu gir(bitirmek için EOF gir): 34 Notu gir(bitirmek için EOF gir): 99 Notu gir(bitirmek için EOF gir): ^Z En büyük not: 99 C++ AKIŞ(STREAM) G/Ç Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 17

21.4.2 get ve getline Üye Fonksiyonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 18 cin.get(): akıştan bir karakter okur (whitespace de olabilir) ve gönderir cin.get( c ): akıştan bir karakter okur ve c ye aktarır

21.4.2 get ve getline Üye Fonksiyonları cin.get(dizi, boyut): 3 argument kabul eder: karakter dizisi, boyut limiti, ve ayırtaç ( default \n ). Diziyi bir destek(tampon) gibi kullanır Ayırtaç görüldüğünde, girdi akışında kalır Diziye Null karakter eklenir Ayırtaç akıştan kaldırılmadıkça, orada kalır cin.getline(dizi, boyut) cin.get(destek, boyut) gibi işlem yapar fakat ayırtacı akıştan kaldırır, diziye yüklemez Diziye Null karakter eklenir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 19

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 20 1 // Fig. 21.12: fig21_12.cpp 2 // Üye fonksiyonlar get, put eof kullanımı. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 int main() 10 { 11 char c; 12 21.4.2 get ve getline Üye Fonksiyonları 13 cout << Girdiden önce, cin.eof() değeri " << cin.eof() 14 << "\neof ile biten bir cümle yaz:\n"; 15 16 while ( ( c = cin.get() )!= EOF ) 17 cout.put( c ); 18 19 cout << "\n Bu sistemdeki EOF : " << c; 20 cout << "\ngirdiden sonra, cin.eof() değeri " << cin.eof() << endl; 21 return 0; 22 } Girdiden önce, cin.eof() değeri 0 EOF ile biten bir cümle yaz: get ve put üye fonksiyonlarının testi^z get ve put üye fonksiyonlarının testi Bu sistemdeki EOF: -1 Girdiden sonra, cin.eof() is 1 1. Initialize variables 2. Input data 2.1 Function call 3. Output Program Output

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 21 1 // Fig. 21.14: fig21_14.cpp 21.4.2 get ve getline Üye Fonksiyonları 2 // getline üye fonksiyonu ile karakter girdisi. 3 #include <iostream> 4 5 6 using std::cout; using std::cin; 1. Initialize variables 7 8 using std::endl; 2. Input 9 10 int main() { 2.1 Function call 11 12 const int BOYUT = 80; char destek[ BOYUT ]; 3. Output 13 14 cout << Bir cümle gir:\n"; 15 cin.getline( destek, BOYUT); 16 Program Output 17 cout << "\ngirilen cümle:\n" << destek << endl; 18 return 0; 19 } Bir cümle gir: getline üye fonksiyonu kullanımı Girilen cümle: getline üye fonksiyonu kullanımı

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 22 21.4.3 istream Üye Fonksiyonları peek, putback ve ignore ignore üye fonkisyonu Karakterlerin belirlenmiş sayısına atlar(default -bir) Belirlenmiş bir ayırtaç bulunduğunda durur(default - EOF, dosya sonuna atlar) putback üye fonksiyonu get ile elde edilen önceki karakteri tekrar akışa yerleştirir peek Akıştan bir sonraki karakteri ( yoketmeden) gönderir

21.4.4 Type-Safe I/O Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 23 << ve >> operatörleri Farklı tip verileri kabul etmek için yüklenir Umulmadık veri ile karşılaşıldığında, error bayrağı oluşur Program kontrolde kalır

21.5 read, gcount ve write ile Formatsız I/O read ve write üye fonksiyonları Formatsız I/O Bellekteki bir karakter dizisine/dizisinden I/O ham byte-ı Veri formatsız olduğundan, fonksiyonlar newline karakterinde durmaz. Örneğin getline nın aksine belirlenmiş karakter sayısına kadar devam eder Belirlenmiş karakter sayısından daha azı okunduğunda, failbit kurulur gcount: Son girdi operasyonunda okunan toplam girdi karakteri sayısını gönderir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 24

21.5 read, gcount ve write ile Formatsız I/O Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 25 1 // Fig. 21.15: fig21_15.cpp 1. Initialize objects 2 // Formatsız I/O - read, gcount ve write ile 3 #include <iostream> 2. Input 4 5 using std::cout; 3. Output 6 using std::cin; 7 using std::endl; 8 9 int main() 10 { 11 const int BOYUT = 80; 12 char destek[ BOYUT ]; 13 Program Output 14 cout << Bir cümle gir:\n"; 15 cin.read( destek, 20 ); 16 cout << "\ngirilen cümle:\n"; 17 cout.write( destek, cin.gcount() ); 18 cout << endl; 19 return 0; 20 } Bir cümle gir: read, write, ve gcount üye fonksiyonlarının kullanımı Girilen cümle: read, write, ve gcou

21.6 Stream Manipulatörleri(Düzenleyicileri) Stream düzenleyici kapasiteleri Alan uzunluğu kurma Duyarlılık kurma Format bayraklarını kurma ve bozma Alandaki doldurma karakterlerini kurma Akışı boşaltma Çıktı akışına yenisatır karakteri ekleme ve akışı boşaltma Çıktı akışaına bir boş karakter ekleme ve girdi akışındaki whitespace karakterini atlama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 26

21.6.1 Integral Stream Bazı: dec, oct, hex ve setbase oct, hex, veya dec: Akıştaki tamsayıların bazını değiştirme. Örnek: int n = 15; cout << hex << n; "F yazar setbase: Tamsayı çıktısının bazını değiştirir <iomanip> yükle Bir tamsayı argüment kabul eder (10, 8, veya 16) cout << setbase(16) << n; Parametreleştirlmiş stream düzenleyici bir argüment alır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 27

21.6.1 Integral Stream Bazı: dec, oct, hex ve setbase 1 // Fig. 21.16: fig21_16.cpp 2 // hex, oct, dec ve setbase stream düzenleyici kullanımı. 3 #include <iostream> 4 5 using std::cout; 1. Load header 6 using std::cin; 7 using std::endl; 1.1 Initialize variables 8 9 #include <iomanip> 2. Input number 10 11 using std::hex; 3. Output in hex 12 using std::dec; 3.1 Output in octal 13 using std::oct; 14 using std::setbase; 3.2 Output in decimal 15 16 int main() 17 { 18 int n; 19 20 cout << Bir tamsayı gir: "; 21 cin >> n; 22 23 cout << n << hexadecimal değeri: " 24 << hex << n << '\n' 25 << dec << n << " oktal değeri: " 26 << oct << n << '\n' 27 << setbase( 10 ) << n << " desimal değeri: " 28 << n << endl; 29 30 return 0; C++ AKIŞ(STREAM) G/Ç Nuri 31 ÖZALP } (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 28

21.6.1 Integral Stream Bazı: dec, oct, hex ve setbase Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 29 Bir tamsayı gir: 20 20 hexadecimal değeri: 14 20 oktal değeri: 24 20 desimal değeri: 20

21.6.2 Floating-Point Duyarlılık (precision, setprecision) precision Üye fonksiyonu Desimal nokta sayısını kurar cout.precision(2); cout.precision() o anki duyarlılık değerini gönderir setprecision Parametreleştirlmiş stream düzenleyici Tüm Parametreleştirlmiş stream düzenleyiciler gibi, <iomanip> gerekli Duyarlılığı belirler: cout << setprecision(2) << x; Her iki yöntem için de, yeni değer kurulana kadar eskisi geçerli kalır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 30

21.6.3 Alan Uzunluğu(Field Width) (setw, width) ios uzunluk üye fonksiyonu Alan uzunluğunu kurar (çıktı karakterlerinin yer sayısı veya girdi karakterlerinin sayı) Önceki uzunluğu gönderir İşlenen değerler uzunluktan daha kısa ise, karakterler sağa yaslanarak doldurulur Değerler kesilmez- tüm rakamlar basılır cin.width(5); setw stream düzenleyici cin >> setw(5) >> string; Boşluk karakteri için yer ayırmayı unutma! Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 31

1 // fig21_18.cpp 21.6.3 Alan Uzunluğu(Field Width) (setw, width) 2 // width(uzunluk) üye fonksiyonu kullanımı 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 int main() 10 { 1. Initialize variables 2. Input sentence 2.1 Set width 2.2 Loop and change width 3. Output 11 int w = 4; 12 char string[ 10 ]; 13 14 cout << Bir cümle gir:\n"; 15 cin.width( 5 ); 16 17 while ( cin >> string ) { // durmak için EOF gir 18 cout.width( w++ ); 19 cout << string << endl; 20 cin.width( 5 ); 21 } 22 23 return 0; 24 } C++ AKIŞ(STREAM) G/Ç Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 32

21.6.3 Alan Uzunluğu(Field Width) (setw, width) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 33 Bir cümle gir: Bu bir width üye fonksiyonu testidir Bu bir widt h üye fonk siyo nu test idir ^z

21.6.4 Kullanıcı Tanımlı Manipulatörler Kendi stream düzenleyicimizi oluşturabiliriz bell ret (taşıma dönüşü) tab endline Parametreleştirilmiş stream düzenleyici Kurulum klavuzuna bakınız Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 34

21.7 Stream Format Durumları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 35 Format bayrakları (flag) Stream I/O operasyonları sırasında uygulanacak formatı belirler setf, unsetf ve flags Bayrak kurumlarını kontrol eden üye fonksiyonlar

21.7.1 Format Durum Bayrakları Format Durum Bayrakları ios sınıfında bir numaralandırma olarak tanımlanır Üye fonksiyonlar tarafından kontrol edilebilir flags tüm bayrakların durumunu temsil eden bir değer belirler İlk seçimleri içeren bir long değer gönderir setf tek parametre- bayrak kur unsetf bayrakları kaldırır setiosflags - parametreleştirilmiş stream düzenleyici bayrakları kurar resetiosflags parametreleştirilmiş stream düzenleyici, unsetf gibi aynı fonksiyonlara sahip Bayraklar bitwise OR ( ) kullanılarak birleştirlebilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 36

21.7.2 Uç sıfırlar ve Desimal noktalar (ios::showpoint) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 37 ios::showpoint Tamsayılı bir float sayının desimal değerlerini sıfırları ile birlikte yazar cout.setf(ios::showpoint) cout << 79; 79 sayısı 79.00000 olarak yazılır Sıfırların sayısı duyarlılık kurulumu ile belli olur

21.7.3 Sağlama (ios::left, ios::right, ios::internal) ios::left Sola yaslayarak yazar -fazlalık alan sağda boşluk olur ios::right Default kurulum Sağa yaslayarak yazar Karakter yaslamaları için fill üye fonksiyonu setfill parametrik akış düzenleyici Default karakter -boşluk Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 38

21.7.3 Sağlama (ios::left, ios::right, ios::internal) internal flag (bayrak) Sayının işareti sola-yaslanmış(left-justified) Sayının büyüklüğü sağa-yaslanmış( right-justified) Karakter doldurma ile boşluklara müdahale static veri üyesi ios::adjustfield left, right ve internal flag ları içerir left, right veya internal sağlama bayrakları kurulduğunda, ios::adjustfield setf e ikinci argüment olmalı cout.setf( ios::left, ios::adjustfield); Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 39

1 // Fig. 21.22: fig21_22.cpp 2 // sola yaslama sağa yaslama 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <iomanip> 9 10 using std::ios; 11 using std::setw; 12 using std::setiosflags; 13 using std::resetiosflags; 14 15 int main() 16 { 17 int x = 12345; 18 19 cout << "Default sağa yaslama:\n" 20 << setw(10) << x << "\n\nüye fonksiyonları kullanarak" 21 << "\n ios::left i kurmak için setf kullan:\n" << setw(10); 22 23 cout.setf( ios::left, ios::adjustfield ); 24 cout << x << "\ndefault u geri yüklemek için unsetf kullan:\n"; 25 cout.unsetf( ios::left ); 26 cout << setw( 10 ) << x 27 << "\n\nparametrik akış düzenleyici kullanarak" 28 << "\nios::left i kurmak için setiosflags kullan:\n" 29 << setw( 10 ) << setiosflags( ios::left ) << x 30 << "\ndefault u geri yüklemek için resetiosflag kullan:\n" 31 << setw( 10 ) << resetiosflags( ios::left ) 32 << x << endl; 33 return 0; 34 } 21.7.3 Sağlama (ios::left, ios::right, ios::internal) 1. Initialize variable 2. Use parameterized stream manipulators 3. Output C++ AKIŞ(STREAM) G/Ç Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 40

21.7.3 Sağlama (ios::left, ios::right, ios::internal) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 41 Default sağa yaslama: 12345 Üye fonksiyonları kullanarak ios::left i kurmak için setf kullan: 12345 default u geri yüklemek için unsetf kullan: 12345 parametrik akış düzenleyici kullanarak ios::left i kurmak için setiosflags kullan: 12345 default u geri yüklemek için resetiosflag kullan: 12345

21.7.4 Tamponlama (fill, setfill) fill üye fonksiyonu Doldurma karakterini belirler default - boşluk Önceki yaslama (tamponlama) karakterine döner cout.fill( '*'); setfill düzenleyici Ayrıca doldurma karakterini kurar cout << setfill ('*'); Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 42

1 // Fig. 21.24: fig21_24.cpp 2 // fill ve setfill üye fonksiyonu kullanımı 21.7.4 Tamponlama (fill, setfill) 3 // Yazılacak değerden daha geniş olan alanlar için 4 // doldurma karakterini değiştiren düzenleyici 5 #include <iostream> 1. Load header 1.1 Initialize variable 6 7 using std::cout; 8 using std::endl; 9 10 #include <iomanip> 11 12 using std::ios; 13 using std::setw; 14 using std::hex; 15 using std::dec; 16 using std::setfill; 17 18 int main() 19 { 20 int x = 10000; C++ AKIŞ(STREAM) G/Ç Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 43

21 21.7.4 Tamponlama (fill, setfill) 22 cout << x << " in sağ ve sol yaslamalı yazılışı\n" 23 << ayrıca iç düzenlemeli hex yazılışı.\n" 24 << default doldurma karakteri(boşluk)kullanarak:\n"; 25 cout.setf( ios::showbase ); 26 cout << setw( 10 ) << x << '\n'; 27 cout.setf( ios::left, ios::adjustfield ); 28 cout << setw( 10 ) << x << '\n'; 29 cout.setf( ios::internal, ios::adjustfield ); 30 cout << setw( 10 ) << hex << x; 31 32 cout << "\n\ndeğişik doldurma karakterleri ile:\n"; 33 cout.setf( ios::right, ios::adjustfield ); 34 cout.fill( '*' ); 35 cout << setw( 10 ) << dec << x << '\n'; 36 cout.setf( ios::left, ios::adjustfield ); 37 cout << setw( 10 ) << setfill( '%' ) << x << '\n'; 38 cout.setf( ios::internal, ios::adjustfield ); 39 cout << setw( 10 ) << setfill( '^' ) << hex << x << endl; 40 return 0; 41 } 2. Set fill character 3. Output Program Output 10000 in sağ ve sol yaslamalı yazılışı Ayrıca iç düzenlemeli hex yazılışı. Default doldurma karakteri(boşluk) kullanarak: 10000 10000 0x 2710 Değişik doldurma karakterleri ile: *****10000 10000%%%%% 0x^^^^2710 C++ AKIŞ(STREAM) G/Ç Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 44

21.7.5 Integral Stream Bazı (ios::dec, ios::oct, ios::hex, ios::showbase) ios::basefield static üye setf ile ios::adjustfield e benzer şekilde kullanım ios::oct, ios::hex ve ios::dec flag bit-lerini içerir Tamsayıların oktal, hexadecimal ve desimal değerler olarak ele alınmasını belirler Default desimal stream aktarmalar için default girilen forma bağlıdır 0 ile başlayan tamsayılar oktal kabul edilir 0x veya 0X ile başlayan hexadecimal Bir baz belirlendikten sonra, kurulum değiştirilinceye kadar aynı kalır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 45

21.7.6 Floating-Point Sayılar; Bilimsel Gösterimi(ios::scientific, ios::fixed) ios::scientific Reel sayının çıktısını bilimsel notasyonda verir: 1.946000e+009 ios::fixed Desimalin sağında belli sayıda rakam göstermeye zorlar (precision ile belirlenir) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 46

21.7.6 Floating-Point Sayılar; Bilimsel Gösterimi(ios::scientific, ios::fixed) static veri üyesi ios::floatfield ios::scientific ve ios::fixed içerir setf deki ios::adjustfield ve ios::basefield de benzer şekilde kullanım cout.setf(ios::scientific, ios::floatfield); cout.setf(0, ios::floatfield) reel sayı çıktıları için default formata geçer Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 47

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 48 1 // Fig. 21.26: fig21_26.cpp 21.7.6 Floating-Point Sayılar; Bilimsel Gösterimi(ios::scientific, ios::fixed) 2 // sistem default, bilimsel ve sabitlenmiş formatta 3 // reel sayılar. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 using std::ios; 9 10 int main() 11 { 12 double x =.001234567, y = 1.946e9; 13 14 cout << default format ile göster:\n" 15 << x << '\t' << y << '\n'; 16 cout.setf( ios::scientific, ios::floatfield ); 17 cout << bilimsel format ile göster:\n" 18 << x << '\t' << y << '\n'; 19 cout.unsetf( ios::scientific ); 20 cout << unsetf den sonra default formatta göster:\n" 21 << x << '\t' << y << '\n'; 22 cout.setf( ios::fixed, ios::floatfield ); 23 cout << sabitlenmiş format ile göster:\n" 24 << x << '\t' << y << endl; 25 return 0; 26 } default format ile göster: 0.00123457 1.946e+009 bilimsel format ile göster: 1.234567e-003 1.946000e+009 unsetf den sonra default formatta göster: 0.00123457 1.946e+009 sabitlenmiş format ile göster: 0.001235 1946000000.000000 1. Initialize variables 2. Set flags 3. Output Program Output

21.7.7 Uppercase/Lowercase Kontrol (ios::uppercase) ios::uppercase Bilimsel notasyonda E gösterimi 4.32E+010 hexadecimal sayıların X ile gösterimi tüm harf değerler büyük harf olur 75BDE Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 49

21.7.8 Format bayraklarını kurma ve yenileme(flags, setiosflags, resetiosflags) flags üye fonksiyonu Format bayrağının o anki değerini argümentsiz gönderir (long değer olarak) long argumenti ile, format bayrağını belirlendiği gibi kurar Ön kurulumları gönderir setf üye fonksiyonu Argümentinde verilen format bayraklarını kurar Önceki flag kurulumunu bir long değer olarak gönderir long previousflagsettings = cout.setf( ios::showpoint ios::showpos ); Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 50

21.7.8 Format bayraklarını kurma ve yenileme(flags, setiosflags, resetiosflags) İki long argument ile setf cout.setf( ios::left, ios::adjustfield ); ios::adjustfield bitlerini temizler ios::left kurar setf nin bu versiyonu aşağıdakiler ile kullanılabilir: ios::basefield (ios::dec, ios::oct, ios::hex) ios::floatfield (ios::scientific, ios::fixed) ios::adjustfield (ios::left, ios::right, ios::internal ) unsetf Belirlenmiş bayrakları yeniden kurar Önceki kurumlara döner Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 51

1 // Fig. 21.28: fig21_28.cpp 21.7.8 Format bayraklarını kurma ve yenileme(flags, setiosflags, resetiosflags) 2 // flag üye fonksiyonları kullanımı. 3 #include <iostream> 4 5 using std::cout; 1. Initialize variables 6 using std::endl; 7 using std::ios; 2. Set flags 8 9 3. Output 10 int main() 11 { 12 int i = 1000; 13 double d = 0.0947628; 14 15 cout << flag değişkeninin değeri: " 16 << cout.flags() 17 << "\norjinal formatta int ve double yaz:\n" 18 << i << '\t' << d << "\n\n"; 19 long originalformat = 20 cout.flags( ios::oct ios::scientific ); 21 cout << flag değişkeninin değeri: " 22 << cout.flags() 23 << "\nyeni formatta int ve double yazımı-\n" 24 << flag üye fonksiyonu kullanılarak belirlenmiş:\n" 25 << i << '\t' << d << "\n\n"; 26 cout.flags( originalformat ); 27 cout << flag değişkeninin değeri: " 28 << cout.flags() 29 << "\ndeğerleri tekrar orijinal formatta yaz:\n" 30 << i << '\t' << d << endl; 31 return 0; C++ AKIŞ(STREAM) G/Ç Nuri 32 ÖZALP } (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 52

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 53 21.7.8 Format bayraklarını kurma ve yenileme(flags, setiosflags, resetiosflags) flag değişkeninin değeri: 0 original formatta int ve double yaz: 1000 0.0947628 flag değişkeninin değeri: 4040 yeni formatta int ve double yazımı flag üye fonksiyonu kullanılarak belirlenmiş: 1750 9.476280e-002 flag değişkeninin değeri : 0 değerleri tekrar orijinal formatta yaz: 1000 0.0947628

21.8 Stream Hata Durumları eofbit EOF görüldükten sonra bir girdi akışı kurar Eğer cin de EOF ile karşılaşılırsa cin.eof() true gönderir failbit Format hatası oluştuğunda bir akış kurulur Eğer akış operasyonu başarısız olursa cin.fail() true gönderir Normal durumlarda bu hatalardan kurtulunur Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 54

21.8 Stream Hata Durumları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 55 badbit Veri kaybı ile sonuçlanan hata oluştuğunda kurulur Akış operasyonu başarısız ise, cin.bad() true gönderir Geri dönüşü yok goodbit eofbit, failbit veya badbit kurulmadığında, bir akış için kurulur Eğer bad, fail ve eof tümü false gönderecekse, cin.good() true gönderir. I/O operasyonları sadece good akışlarda kullanılmalı rdstate Akışın durumunu gönderir Akış tüm durum bitlerini inceleyen bir switch deyimiyle test edilmelidir Durumu belirlemek için eof, bad, fail, ve good kullanmak daha kolaydır

21.8 Stream Hata Durumları clear Akışın durumunu good a çevirmek için kullanılır cin.clear() cin i temizler ve akış için goodbit kurar cin.clear( ios::failbit ) aslında failbit kurar Kullanıcı tanımlı tiplerde hata oluştuğunda bu kullanılabilir Diğer operasyonlar operator! Eğer badbit veya failbit kuruluysa true gönderir operator void* Eğer badbit veya failbit kuruluysa false gönderir Dosya işleme için kullanışlı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 56

21.8 Stream Hata Durumları 1 // Fig. 21.29: fig21_29.cpp 2 // Hata durumlarını test etme. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::cin; 8 9 int main() 10 { 11 int x; 12 cout << Kötü bir girdi operasyonundan önce:" 13 << "\ncin.rdstate(): " << cin.rdstate() 14 << "\n cin.eof(): " << cin.eof() 15 << "\n cin.fail(): " << cin.fail() 16 << "\n cin.bad(): " << cin.bad() 17 << "\n cin.good(): " << cin.good() 18 << "\nbir tamsayı bekliyor fakat karakter giriliyor: "; 19 cin >> x; 20 21 cout << "\nkötü bir girdi operasyonundan sonra:" 22 << "\ncin.rdstate(): " << cin.rdstate() 23 << "\n cin.eof(): " << cin.eof() 24 << "\n cin.fail(): " << cin.fail() 25 << "\n cin.bad(): " << cin.bad() 26 << "\n cin.good(): " << cin.good() << "\n\n"; 27 28 cin.clear(); 29 30 cout << " cin.clear()den sonra" 31 << "\ncin.fail(): " << cin.fail() 32 << "\ncin.good(): " << cin.good() << endl; 33 return 0; 34 } 1. Initialize variable 2. Function calls 3. Output C++ AKIŞ(STREAM) G/Ç Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 57

21.8 Stream Hata Durumları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 58 Kötü bir girdi operasyonundan önce: cin.rdstate(): 0 cin.eof(): 0 cin.fail(): 0 cin.bad(): 0 cin.good(): 1 Bir tamsayı bekliyor fakat karakter giriliyor: A Kötü bir girdi operasyonundan sonra: cin.rdstate(): 2 cin.eof(): 0 cin.fail(): 1 cin.bad(): 0 cin.good(): 0 cin.clear() den sonra cin.fail(): 0 cin.good(): 1

21.9 Output Stream-i Input Stream-e bağlama tie üye fonksiyonu bir istream ve bir ostream operasyonunu senkronize eder Çıktı ardışık girdiden önce görünür cin ve cout için otomatik olarak yapılır inputstream.tie( &outputstream ); inputstream e outputstream e bağlar cin.tie( &cout) otomatik yapılır inputstream.tie( 0 ); Bir çıktı akışında inputstream i çözer (bağını koparır) Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ AKIŞ(STREAM) G/Ç 59

Bölüm 22 - C++ Şablonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 1 İçerik 22.1 Giriş 22.2 Sınıf Şablonları 22.3 Sınıf Şablonları ve Tip-olmayan Parametreler 22.4 Şablonlar ve Kalıtsallık 22.5 Şablonlar ve Arkadaşlar 22.6 Şablonlar ve Statik Üyeler

22.1 Giriş Şablonlar İlişkili fonksiyonların veya sınıfların geniş bir alanını kolaylıkla oluşturur Fonksiyon şablonu- ilişkili fonksiyonların bir karbon-kopyası Şablon fonksiyonu- bir fonksiyon şablonundan oluşturulan özel bir fonksiyon Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 2

22.2 Sınıf Şablonları Sınıf Şablonları Genel sınıfların özel-tip versiyonlarına izin verir Format: template <class T> class SınıfAdı{ tanım } "T" kullanmak gerekli değil, herhangi bir belirteç yazılabilir Bu sınıftan bir nesne yaratmak için SınıfAdı< tip > benimnesnem; yaz Örnek : Stok< double > ciftstok; Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 3

22.2 Sınıf Şablonları Şablon sınıfı fonksiyonlar Normal şekilde deklare edilir fakat template<class T> yi takip eder Sınıftaki genel veri T tipinde listelenir İkili hedef kararlılık operatörür kullanılır Tanımlaması: template<class T> BenimSinifim< T >::BenimSinifim(int boyut) { } Dizim = new T[boyut]; Oluşturucu tanımı- T tipinde bir dizi oluşturur Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 4

1 // Fig. 22.3: ssstok1.h 2 // Sınıf Şablonu Stok 3 #ifndef SSSTOK1_H 4 #define SSSTOK1_H 5 6 template< class T > 7 class Stok { 8 public: 22.2 Sınıf Şablonları 9 Stok( int = 10 ); // default oluşturucu (stok boyutu 10) 10 ~Stok() { delete [] stokptr; } // yokedici 11 bool push( const T& ); // bir elemanı stoka at 12 bool pop( T& ); // stoktan bir eleman çıkar 13 private: 14 int boyut; // # of elements in the stack 15 int tap; // tap elemanın yeri 16 T *stokptr; // stok a pointer 17 18 bool isempty() const { return tap == -1; } // utility 19 bool isfull() const { return tap == boyut - 1; } // fonksiyonlar 20 }; 21 22 // default boyut 10 lu oluşturucu 23 template< class T > 24 Stok< T >::Stok( int s ) 25 { 26 boyut = s > 0? s : 10; 27 tap = -1; // Başlangıçta Stok boş 28 stokptr = new T[ boyut]; // elemanlara yer aç 29 } C++ ŞABLONLARI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 5

30 31 // Stoka bir eleman ekle 22.2 Sınıf Şablonları 32 // başarılı ise 1 aksi halde 0 gönder 33 template< class T > 34 bool Stok< T >::push( const T &ekdeger ) 35 { 36 if (!isfull() ) { 37 stokptr[ ++tap ] = ekdeger; // üyeyi Stoka yerleştir 38 return true; // ekleme başarılı 39 } 40 return false; // ekleme başarısız 41 } 42 43 // Bir elemanı Stoktan çıkar 44 template< class T > 45 bool Stok< T >::pop( T &aldeger ) 46 { 47 if (!isempty() ) { 48 aldeger = stokptr[ tap-- ]; // Stoktan üyeyi çıkar 49 return true; // çıkarma başarılı 50 } 51 return false; // çıkarma başarısız 52 } 53 54 #endif C++ ŞABLONLARI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 6

55 // Fig. 22.3: fig22_03.cpp 56 // Stok şablonu için test programı 22.2 Sınıf Şablonları 57 #include <iostream> 58 59 using std::cout; 60 using std::cin; 61 using std::endl; 62 63 #include ssstok1.h" 64 65 int main() 66 { 67 Stok< double > ciftstok( 5 ); 68 double f = 1.1; 69 cout << Elemanları ciftstok a ekle\n"; 70 71 while ( ciftstok.push( f ) ) { // başarılı ise doğru gönder 72 cout << f << ' '; 73 f += 1.1; 74 } 75 76 cout << "\nstok dolu. Ekleyemiyor" << f 77 << "\n\nciftstok tan eleman çıkarma\n"; 78 79 while ( ciftstok.pop( f ) ) // başarılı ise doğru gönder C++ ŞABLONLARI Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 7

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 8 80 cout << f << ' '; 81 22.2 Sınıf Şablonları 82 cout << "\nstok boş. Çıkarma yapılamıyor\n"; 83 84 Stok< int > intstok; 85 int i = 1; 86 cout << "\n Elemanları intstok a ekle \n"; 87 88 while ( intstok.push( i ) ) { // başarılı ise doğru gönder 89 cout << i << ' '; 90 ++i; 91 } 92 93 cout << "\nstok dolu. Ekleyemiyor" << i 94 << "\n\nintstok tan eleman çıkar\n"; 95 96 while ( intstok.pop( i ) ) // başarılı ise doğru gönder 97 cout << i << ' '; 98 99 cout << "\nstok boş. Çıkarma yapılamıyor\n"; 100 return 0; 101 }

22.2 Sınıf Şablonları Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 9 elemanları ciftstok a ekle 1.1 2.2 3.3 4.4 5.5 Stok dolu. Ekleyemiyor 6.6 ciftstok tan eleman çıkarma 5.5 4.4 3.3 2.2 1.1 Stok boş. Çıkarma yapılamıyor elemanları intstok a ekle 1 2 3 4 5 6 7 8 9 10 Stok dolu. Ekleyemiyor 11 inttstok tan eleman çıkarma 10 9 8 7 6 5 4 3 2 1 Stok boş. Çıkarma yapılamıyor

22.3 Sınıf Şablonları ve Tip-olmayan Parametreler Tip-olmayan parametreler şablonlarda kullanılabilir Default argument const olarak algılanır Örnek: template< class T, int elemanlar > Stok< double, 100 > ensonsatis; Stok< double, 100> tipi nesne tanımlar Bu sınıf tanımında görülebilir: T stoktutucu[ elemanlar ]; //stok u tutan dizi Çalışma zamanında dinamik düzenleme yerine, derleme zamanında dizi oluşturur Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 10

22.3 Sınıf Şablonları ve Tip-olmayan Parametreler Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 11 Sınıflar önemli olmayabilir Dizi şablon sınıfı için, Dizi<benimTipim> şeklinde sınıf adı tanımlarsak, bu yeni sınıf benimtipim için olan sınıf şablonundan üstte kalır Şablon alttaki tipler için kalır

22.4 Şablonlar ve Kalıtsallık Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 12 Bir sınıf şablonu bir şablon sınıfından oluşturulabilir Bir sınıf şablonu bir şablon olmayan sınıftan oluşturulabilir Bir şablon sınıfı bir sınıf şablonundan oluşturulabilir Bir şablon olmayan sınıf bir sınıf şablonundan oluşturulabilir

22.5 Şablonlar ve Arkadaşlar Arkadaşlığa bir sınıf şablonu ve aşağıdakiler arasında izin verilir: Global fonksiyon Başka bir sınıfın üye fonksiyonu Tüm sınıf friend(arkadaş) fonksiyonları X sınıf şablonunun içinde tanımlama : friend void f1(); f1() tüm şablon sınıflarının bir friend -i friend void f2( X< T > & ); f2( X< int > & ) sadece X< int > Aynısı float, double v.s. ye uygulanabilir. friend void A::f3(); in friend -i. A sınıfının üye fonksiyonu f3, tüm şablon sınıflarının friend -i Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 13

22.5 Şablonlar ve Arkadaşlar Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 14 friend void C< T >::f4( X< T > & ); C<float>::f4( X< float> & ) sadece X<float> sınıfının friend -i friend sınıfları friend class Y; Y nin her üye fonksiyonu X den oluşturulan her şablon sınıfı ile arkadaş friend class Z<T>; Z<float> sınıfı X<float> sınıfının bir friend -i v.s.

22.6 Şablonlar ve Statik Üyeler Şablon-olmayan sınıf static veri üyeleri tüm nesneler arasında paylaşılır Şablon sınıfları Her sınıf (int, float, v.s.) kendi static veri üyeleri kopyasına sahiptir. static değişkenler dosya hedefinde belirlenir Her şablon sınıf ı kendi static veri üyeleri kopyasını alır. Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA C++ ŞABLONLARI 15

Bölüm 23 Harici Durum Kontrolü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 1 İçerik 23.1 Giriş 23.2 Harici Durum Kontrolü Ne Zaman Kullanılır 23.3 Diğer Hata-Kontrol Teknikleri 23.4 C++ Harici Durum Temelleri: try, throw, catch 23.5 Basit Bir Örnek: Sıfıra Bölme 23.6 Harici Durumdan Kurtulma 23.7 Harici Durum Yakalama 23.8 Harici Durumdan Tekrar Kurtulma 23.9 Harici Durum Belirleme 23.10 Beklenmeyen Harici Durum Kontrolü 23.11 Stok Çözme 23.12 Oluşturucu, Yokedici ve Harici Durum Kontrolü 23.13 Harici Durum ve Kalıtsallık 23.14 Yeni Hataları İşleme 23.15 auto_ptr Sınıfı ve Dinamik Bellek Düzenleme 23.16 Standard Kütüphane Harici Durum Hiyerarşisi

23.1 Giriş Hatalar hatanın oluştuğu noktada düzeltilir Düzenli hata kontrol uygulandığında kontrol etmek kolaydır Uygulamaları okumak ve kodun nasıl çalışdığını görmek zor Harici durum kontrolü Açık, güçlü ve hatasız program yapma C++ hata kontrol kodlarını programın ana satırı ndan kaldırır Sık hatalar new belleği düzenlettirmeme Dizi indisi sınır dışı Sıfır ile bölme Geçersiz fonksiyon parametresi Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 2

23.1 Giriş Harici durum kontrolü- hatayı oluşmadan yakala Eşzamanlı hatalarla uğraşır (sıfırla bölme gibi) Diğerleri ile uğraşmaz- disk I/O tamamlaması, fare klikleri Sistem hatayı onardığında kullanılır Harici durum kontrolü onarma prosedürü Tipik kullanım yeri hata ile oluştuğu yerden başka bir yerde uğraşıldığı zaman Program takılıyorsa fakat hatasız kapanması gerekiyorsa kullanışlı Harici durum kontrolü program kontrolü için kullanılmamalı Program performansına zarar verebilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 3

23.1 Giriş Harici Durum Kontrolü hata toleransını geliştirir Hata işleme kodu yazmak daha kolay Hangi tip harici durum yakalanacağını belirler Çoğu program tek olayı kontrol eder Buradaki teknikler çoklu olayları kontrol eder (windows NT, OS/2, bazı UNIX) Bir fonksiyon veya kod bloğu kontrolünden dönmenin bir başka yolu Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 4

23.2 Harici Durum Kontrolü Ne Zaman Kullanılır Hata kontrolü aşağıdakiler için kullanılmalı: Harici durumların işlenmesi Doğrudan uğraşılamayan bileşenlerin kontrolü Sıklıkla kullanılan sorunlu bileşenler (kütüphaneler, fonksiyonlar, sınıflar) Düzgün hata işleme gerektiren büyük projeler Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 5

23.3 Diğer Hata-Kontrol Teknikleri assert kullan Bildirim false ise program durur Harici durumu gözardı et Sadece kişisel programlarda kullan! Programdan çık Ciddi olmayan hatalarda uygun Önemli görev yapan programlarda uygun değil Hata belirteci kullan Program hatanın olduğu her noktada belirteci kontrol etmek zorunda değil Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 6

23.3 Diğer Hata-Kontrol Teknikleri Hata durumu için test hata mesajı ilet ve exit çağır Hata kodunu gönder setjump ve longjump <csetjmp> da Hata kontrolü çağıran içiiçe fonksiyonları atla. Tehlikeli otomatik nesneler için yokedici çağırmaksızın stoku boşaltır (daha sonra görülecek) Özel hatalar Some have dedicated capabilities for handling them Eğer new bellek düzenleme yapamazsa new_handler fonksiyonu problemi halletmek için çalıştırılır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 7

23.4 C++ Harici Durum Temelleri: try, throw, catch Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 8 Eğer bir hata tespit ederse, bir fonksiyon bir harici durum nesnesini kaldırır Nesne tipik bir karakter stringi (hata mesajı ) veya sınıf nesnesidir Harici durum kontrolü var ise, harici durum yakalanır ve düzeltilir Aksi halde program durdurulur

23.4 C++ Harici Durum Temelleri: try, throw, catch Format try bloğunda bir hataya sahip olabilecek kod ekle bir veya daha çok catch blokuyla devam et Her bir catch bloğu bir harici durum kontrolüne sahiptir Eğer harici durum oluşur ve catch bloğundaki parametreye uyarsa catch bloktaki kod çalıştırılır Hiçbir harici durum atılmazsa, kontrol ediciler atlanır ve catch bloktan sonra kontrol oluşur throw noktası harici durumun olduğu noktaya yerleştir Kontrol bir throw noktası gönderemez Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 9

23.5 Basit Bir Örnek: Sıfıra Bölme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 10 try ve catch bloklarının formatına bak Bazı özel durumları vereceğiz

1 // Fig. 23.1: fig23_01.cpp 2 // Harici durum kontrolüne bir basit örnek. 3 // Sıfır ile bölmeyi kontrol etme. 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 10 // Sifirilebolme sınıfı kullanılacak 11 // sıfıra bölme durumunu kaldırma kontrolü 12 class Sifirilebolme { 13 public: 14 Sifirilebolme() 15 : message( sıfıra bölmeye çalışıldı" ) { } 16 const char *nedir() const { return mesaj; } 17 private: 18 const char *mesaj; 19 }; 20 21 // Oran fonksiyonunun tanımı. Sıfıra bölme durumunu 22 // kaldır. 23 double oran( int bolum, int bolen ) 24 { 25 if ( bolen == 0 ) 26 throw Sifirilebolme(); 27 28 return static_cast< double > ( bolum ) / bolen; 29 } 23.5 Basit Bir Örnek: Sıfıra Bölme HARİCİ DURUM KONTROLÜ Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 11

30 31 // Ana program 32 int main() 33 { 34 int sayi1, sayi2; 35 double sonuc; 36 23.5 Basit Bir Örnek: Sıfıra Bölme 37 cout << İki tamsayı gir(son için end-of-file): "; 38 39 while ( cin >> sayi1 >> sayi2 ) { 40 41 // try bloğu haricidurum oluşturacak kodu ve 42 // harici durum oluştuğunda çalıştırılmayacak olan 43 // kodu yakalar 44 try { 45 sonuc = oran( sayi1, sayi2 ); 46 cout << Oran: " << sonuc << endl; 47 } 48 catch (Sifirilebolme hd ) { // harici durum kontrolcüsü 49 cout << Harici durum oluştu: " << hd.nedir() << '\n'; 50 } 51 52 cout << "\niki tamsayı gir (son için end-of-file): "; 53 } 54 55 cout << endl; 56 return 0; // normal sonlanma 57 } HARİCİ DURUM KONTROLÜ Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 12

23.5 Basit Bir Örnek: Sıfıra Bölme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 13 İki tamsayı gir(son için end-of-file): 100 7 Oran: 14.2857 İki tamsayı gir(son için end-of-file): 100 0 Harişci durum oluştu: sıfıra bölmeye çalışıldı İki tamsayı gir(son için end-of-file): 33 9 Oran: 3.66667 İki tamsayı gir(son için end-of-file):^z

23.6 Harici Durumdan Kurtulma throw harici durum oluştuğunu belirtir Çoğunlukla herhangi tipten tek (bazen sıfır) operand operand bir nesne ise, bir harici durum nesnesi çağırır Koşullu ifade atılabilir Bir try blokta referans verilen kod bir harici durumu atabilir Harici durum en yakın kontrolcü ile yakalanır Kontrol o anki try blok unu terkeder ve catch kontrolcüsüne gider (eğer var ise) Örnek (iç fonksiyon tanımı) if ( bolen == 0 ) throw Sifirilebolme(); Bir Sifirilebolme nesnesini atar Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 14

23.6 Harici Durumdan Kurtulma Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 15 Programı sonlandırmak için harici durum gerekmez Fakat, harici durum oluşturan bloğu sonlandırır

23.7 Harici Durum Yakalama Harici durum kontrolcüleri catch bloktadır Format: catch( haricidurumtipi parametreadı){ harici durum kontrol kodu } Eğer argüment tipi throw tip ile uyuşursa yakalanır Yakalanmaz ise bu durumda terminate çağrılır ki bu da (default olarak ) abort çağırır Örnek: catch ( Sifirilebolme hd) { } cout << Harici durum oluştu: " << hd.nedir() <<'\n' Sifirilebolme tipi harici durumu yakalar Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 16

23.7 Harici Durum Yakalama Tüm harici durumları yakalama catch(...) tüm harici durumları yakalar Ne tip harici durum oluştuğunu bilemeyiz Parametre adı yok- nesneye referans veremez Hiçbir kontrolcü atılan nesne ile uyuşmazsa Bir sonraki try blokunu araştır Hiçbir şey bulunamasa, terminate çağrılır bulunursa, kontrol son catch bloktan sonra başlar Eğer bir çok kontrolcü atılan nesne ile uyuşursa, bulunan ilk çalıştırılır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 17

23.7 Harici Durum Yakalama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 18 catch parametresi atılan nesne ile uyuşur eğer Aynı tipten iseler Tam uyuşma gerekli- parçalı duruma izin yok catch parametresi atılan nesnenin bir public baz sınıfı ise catch parametresi bir baz-sınıfı pointer/ referans tipi ve atılan nesne bir türev-sınıfı pointer/ referans tipi ise catch kontrolcüsü bir catch(... ) dir Atılan const nesneler const parametre tipine sahiptir

23.7 Harici Durum Yakalama Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 19 Bırakılmayan kaynaklar Harici durum atıldığında kaynaklar düzenlenebilir catch kontrolcüsü new ile düzenlenene boşluğu siler (delete) ve herhangi açık dosyayı kapatır catch kontolcüsü harici durumları atabilir Harici durumlar sadece dış try bloklarınca işlenebilir

23.8 Harici Durumdan Tekrar Kurtulma Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 20 Harici durumları tekrar atma Bir harici durum kontrolcüsü harici durumu işleyemez ise kullanılır Harici durumu aşağıdaki ile yoket: throw; Argüment yok İlk anda hiçbir harici durum atılmaz ise, terminate çağrılır Kontrolcü herzaman harici durumu (bir işlem bile yapıyor olsa) yokedebilir Tekrar atılan harici durum bir sonraki try bloku ile tespit edilir

1 // Fig. 23.2: fig23_02.cpp 2 // Bir harici durumu tekrar yoketme. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <exception> 9 10 using std::exception; 11 12 void atharicidurum() 13 { 14 // Harici durumu al ve düzenle. 15 try { 16 cout << atharicidurum fonksiyonu\n"; 17 throw exception(); // harici durum oluştur 18 } 19 catch( exception h ) 20 { 23.8 Harici Durumdan Tekrar Kurtulma 21 cout << atharicidurum fonksiyonunda haricidurum kontrol altında\n"; HARİCİ DURUM KONTROLÜ Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 21

23.8 Harici Durumdan Tekrar Kurtulma 22 throw; // daha sonraki işlemler için harici durumu tekrar at 23 } 24 25 cout << Bu da yazılmamalı\n"; 26 } 27 28 int main() 29 { 30 try { 31 atharicidurum(); 32 cout << Bu yazılmamalı\n"; 33 } 34 catch ( exception e ) 35 { 36 cout << main deki harici durum kontrolcüsü\n"; 37 } 38 39 cout << "Program kontrolü main deki catch den sonra devam eder" 40 << endl; 41 return 0; 42 } atharicidurum fonksiyonu atharicidurum fonksiyonunda haricidurum kontrol altında main deki harici durum kontrolcüsü Program kontrolü main deki catch den sonra devam eder Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 22

23.9 Harici Durum Belirleme Harici durum özelleştirmesi (throw listesi) Bir fonksiyon tarafından atılacak harici durumları listele Örnek: int g( double h ) throw ( a, b, c ) { // fonksiyon deyimleri } Fonksiyon listelenmiş harici durumları veya türev tiplerini atabilir Eğer farklı tip atılırsa, unexpected fonksiyonu çağrılır throw() (throw listesi yok ise) anlamı fonksiyon hiçbir harici durumu atmayacak Gerçekte, fonksiyon hala harici durumları atabilir, fakat unexpected (sonra verilecek) çağırır Hiçbir throw listesi belirtilmez ise, fonksiyon her hangi harici durumu atabilir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 23

23.10 Beklenmeyen Harici Durum Kontrolü unexpected fonksiyonu set_unexpected ile belirlenmiş fonksiyonu çağırır Default: terminate terminate fonksiyonu set_terminate ile belirlenmiş fonksiyonu çağırır Default: abort set_terminate ve set_unexpected <exception> deki prototip Fonksiyonlara Pointer (yani fonksiyon adı)alır fonksiyon void göndermeli ve argüment almamalı terminate veya unexpected ile çağrılan son fonksiyona pointer gönderir Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 24

23.11 Stok Çözme Harici durum atıldığında ve özel bir hedefte yakalanmadığında çözülmemiş stok fonksiyonu çağır Bir sonraki try/catch bloğundaki harici durumu yakalamayı dener Harici durumun yakalanmadığı fonksiyon durur Yerel değişkenler yokedilir Kontrol, fonksiyonun çağrıldığı yere döner Eğer kontrol bir try blok gönderirse, harici durumu yakala(catch)mayı dene Aksi halde stoku çöz Harici durum yakalanmazsa, terminate çağrılır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 25

23.12 Oluşturucu, Yokedici ve Harici Durum Kontrolü Oluşturcudaki hata durumunda ne yapmalı? Oluşturucu değer göndermez hatanın görülmesini nasıl sağlarız? Bozuk nesneleri tut ve birinin test etmesini bekle bazı değişkenleri Oluşturucu dışında tanımla Atılan bir harici durum başarısız oluşturucuyu gösterebilir catch kontrolcüsü atılan nesne için bir oluşturucu kopyasına sahip olmalıdır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 26

23.12 Oluşturucu, Yokedici ve Harici Durum Kontrolü Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 27 Oluşturucudaki atılan harici durumlar Yokediciler, harici durum atılmadan önce, tüm tamamlanmış baz-sınıfı nesneler ve üye nesneleri için çağrılır Orijinal olarak stok çözmek için çağrılan Yokedici eğer bir harici durumu atmayla sonuçlanırsa terminate çağrılır Harici durum atılırken eğer nesne kısmi tamamlanmış üyelere sahipse, yokediciler tamamlanmış nesneler için çağrılır

23.12 Oluşturucu, Yokedici ve Harici Durum Kontrolü Kaynak kaçağı Harici durum bir kaynağı veren koddan önce gelir Bir çözüm: kaynak verildiğinde yerel nesneyi tanımla Harici durum oluşmadan önce Yokedici çağrılacak Harici durumları yokediciden yakala(catch) Onları catch blokla devam eden try blokta çağıran kod ekle Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 28

23.13 Harici Durum ve Kalıtsallık Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 29 Harici sınıflar baz sınıflarından türetilebilir Eğer catch bir baz sınıfına bir pointer/referans verirsesürücü sınıflarına da pointer/referans yakalar

23.14 Yeni (new) Hataları İşleme Eğer new belleği düzenleyemezse Eski yöntem- assert fonksiyonu kullan Eğer new 0 gönderirse, abort Programın yeniden toparlanmasına izin verme Modern yöntem (header <new>) new, bad_alloc harici durumunu atar Kullanılan yöntem derleyiciye bağlıdır Bazı derleyicilerde : new yerine new(nothrow) (başarısızlık durumunda new nün 0 göndermesi için) set_new_handler(fonksiyonadı) fonksiyonu- new başarısız olduğunda hangi fonksiyonun çağrılacağını kurar Fonksiyon hiçbir değer göndermez ve hiçbir argüment almaz new, bad_alloc u atmaz Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 30

23.14 Yeni (new) Hataları İşleme new Bellek kazanmaya çalışan döngü Bir new kontrol fonksiyonu aşağıdakilerden birini gerçeklemeli: Diğer dinamik düzenlenmiş belleği silerek, daha fazla belleğin hazır olamsını sağlar ve new operatöründeki döngüye döner bad_alloc tipi bir harici durum atar Programı durdurmak için abort veya exit (header <cstdlib>) fonksiyonunu çağırır Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 31

1 // Fig. 23.5: fig23_05.cpp 2 // Bellek düzenlenmemiş durumunda 3 // bad alloc u atan new gösterimi 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 #include <new> 10 11 using std::bad_alloc; 12 13 int main() 14 { 15 double *ptr[ 50 ]; 16 17 try { 18 for ( int i = 0; i < 50; i++ ) { 19 ptr[ i ] = new double[ 5000000 ]; 20 cout << Düzenlenmiş 5000000 doubles: ptr[ " 21 << i << " ] de \n"; 22 } 23 } 24 catch ( bad_alloc exception) { 25 cout << Harici durum görüldü: " 26 << exception.what() << endl; 27 } 28 29 return 0; 30 } 23.14 Yeni (new) Hataları İşleme HARİCİ DURUM KONTROLÜ Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 32

23.14 Yeni (new) Hataları İşleme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 33 Düzenlenmiş 5000000 doubles: ptr[ 0 ] de Düzenlenmiş 5000000 doubles: ptr[ 1 ] de Düzenlenmiş 5000000 doubles: ptr[ 2 ] de Düzenlenmiş 5000000 doubles: ptr[ 3 ] de Haricidurum görüldü: Allocation Failure

1 // Fig. 23.6: fig23_06.cpp 2 // yeni kontrolcü kurma 3 #include <iostream> 4 5 using std::cout; 6 using std::cerr; 7 8 #include <new> 9 #include <cstdlib> 10 11 using std::set_new_handler; 12 13 void yenikontrolcu() 14 { 15 cerr << yenikontrolcu çağrıldı"; 16 abort(); 17 } 18 19 int main() 20 { 21 double *ptr[ 50 ]; 22 set_new_handler( yenikontrolcu ); 23 24 for ( int i = 0; i < 50; i++ ) { 25 ptr[ i ] = new double[ 5000000 ]; 26 27 cout << Düzenlenmiş 5000000 doubles : ptr[ " 28 << i << " ] de \n"; 29 } 30 31 return 0; 23.14 Yeni (new) Hataları İşleme HARİCİ DURUM KONTROLÜ Nuri 32 ÖZALP } (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 34

23.14 Yeni (new) Hataları İşleme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 35 Düzenlenmiş 5000000 doubles: ptr[ 0 ] de Düzenlenmiş 5000000 doubles: ptr[ 1 ] de Düzenlenmiş 5000000 doubles: ptr[ 2 ] de Düzenlenmiş 5000000 doubles: ptr[ 3 ] de yenikontrolcu çağrıldı

23.15 auto_ptr Sınıfı ve Dinamik Bellek Düzenleme Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 36 Dinamik belleğe pointer delete komutundan önce haricidurum oluşursa bellek sızması olabilir Bunu halletmek için auto_ptr (header <memory> ) sınıf şablonu kullan auto_ptr nesnesi pointer gibi davranır yokedildiğinde işaret ettiği noktayı otomatik olarak siler Normal pointer gibi * ve -> kullanabilir

1 // Fig. 23.7: fig23_07.cpp 2 // auto_ptr kullanımı 23.15 auto_ptr Sınıfı ve Dinamik Bellek Düzenleme 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <memory> 9 10 using std::auto_ptr; 11 12 class Integer { 13 public: 14 Integer( int i = 0 ) : deger( i ) 15 { cout << Integer için oluşturucu " << deger << endl; } 16 ~Integer() 17 { cout << Integer için yokedici" << deger << endl; } 18 void setinteger( int i ) { deger = i; } 19 int getinteger() const { return deger; } HARİCİ DURUM KONTROLÜ Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA 37

Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 38 20 private: 21 int deger; 23.15 auto_ptr Sınıfı ve Dinamik Bellek Düzenleme 22 }; 23 24 int main() 25 { 26 cout << Bir integer i işaret eden " 27 << bir auto_ptr nesnesi oluşturma \n"; 28 29 auto_ptr< Integer > ptrtointeger( new Integer( 7 ) ); 30 31 cout << Integer i düzenlemek için auto_ptr kullanma\n"; 32 ptrtointeger->setinteger( 99 ); 33 cout << setinteger dan sonra Integer: " 34 << ( *ptrtointeger ).getinteger() 35 << "\nprogram sonlanıyor" << endl; 36 37 return 0; 38 } Bir integer i işaret eden bir auto_ptr nesnesi oluşturma Integer için oluşturucu 7 Using the auto_ptr to manipulate the Integer setinteger dan sonra Integer: 99 Program sonlanıyor Integer için yokedici 99

23.16 Standard Kütüphane Harici Durum Hiyerarşisi Harici durumlar kategorilere ayrılır Harici durum hiyerarşisi Baz sınıfı exception (header <exception>) Fonksiyon what() uygun hata fonksiyonu atar Türev sınıfları: runtime_error ve logic_error (header <stdexcept>) logic_error sınıfı Program mantığında hata-düzgün kod yazımıyla önlenir Türev sınıfları: invalid_argument geçersiz argüment fonksiyona geçer length_error maksimum boyuttan büyük uzunluk kullanılmış out_of_range indis uzunluğu dışı Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 39

23.16 Standard Kütüphane Harici Durum Hiyerarşisi runtime_error sınıfı Çalışma zamanında tespit edilen hatalar Türev sınıfları: overflow_error - aritmetik overflow underflow_error - aritmetik underflow exception den türeyen diğer sınıflar C++ özellikleri ile atılan harici durumlar new - bad_alloc dynamic_cast - bad_cast typeid - bad_typeid throw listeside std::bad_exception yaz unexpected(), set_unexpected ile kurulan fonksiyonu çağırmak yerine bad_exception ı atar Nuri ÖZALP (ANKARA ÜNİVERSİTESİ) İLERİ PROGRAMLAMA HARİCİ DURUM KONTROLÜ 40