Download as rtf, pdf, or txt
Download as rtf, pdf, or txt
You are on page 1of 101

C++ NASIL BR PROGRAMLAMA DLDR? C++ nesne ynelimli programlama tekniinin uygulanabilmesi iin C'nin geniletilmi bir biimidir.

Nesne ynelimli programlama(object oriented programming) teknii ve C++ B.Stroustroup tarafndan gelitirilmitir. Tasarm 70'li yllarn ikinci yarsndan balanm olsa da btn dnyada yaygnlamas ve kabul grmesi 80'li yllarn sonlarna doru mmkm olmutur. Nesne ynelimli programlama teknii(NYP) zellikle byk kodlarn stesinden gelebilmek amacyla tasarlanmtr. Tasarm C++ zerinde yaplm olmasna karn bugn pek ok yksek seviyeli programlama dilleri bu teknii desteklemektedir. C++ ve nesne ynelimli programlama tekniinin en belirgin uygulama alanlarndan birisi WINDOWS altnda programlamadr. WINDOWS karmak ve yksek yksek seviyeli bir iletim sistemidir. WINDOWS altnda program gelitirebilmek iin uzun kodlar yazmak gerekir. Bu nedenle WINDOWS altnda C ile deil C++ ile ve NYP tekniini kullanarak program yazmak daha etkin bir zmdr. NYP tekniinin uygulanabilmesi iin altmz sistemin kaynaklarnn yeterince geni olmas gerekir. (Yani hzl bir mikro ilemci, byk RAM ve DISK ve iyi bir iletim sistemi) C++'IN C'DEN FARKLILIKLARI

NYPT LE DORUDAN LKS OLMAYAN FARLILIKLARI VE FAZLALIKLARI

SINIF YAPISI

ki dzeyde deerlendirilebilir. 1-)NYPT ile dorudan ilikisi olayan farkllklar ve fazlalklar 2-)Snf yaps Snf(class) C'deki yap(struct)'lara benzer bir veri yapsdr. NYPT snflar kullanlarak program yazlmas tekniidir. Kursun %80'i snf yapsnn yaps ve kullanlmas zerine ayrlmtr. C++'IN NYPT LE DORUDAN LKS OLMAYAN FARLILIKLARI VE FAZLALIKLARI C++ derleyicileri C derleyicisini de derleyicisi demek hem C hem de C++ dosyann uzantsna bakarak kodun C'de olduuna karar verir. C'de ise uzants cpp'dir. iermek zorundadr. Yani C++ derleyicisi demektir. Derleyici mi yoksa C++'ta m yazlm c, C++'ta yazlmsa uzants

1-) C++'ta yerel deikenlerin bildirimleri bloklarn banda yaplmak zorunda deildir.

Standart C'de yerel deikenler bloklarn banda bildirilmek zorundadr. Yani kme parantezi aldktan sonra daha hibir fonksiyon arlmadan ve ilem yaplmadan yaplmaldr. Bu tasarmn nedeni programcnn bildirimin yerini kolay bulabilmesini salamaya yneliktir. Oysa C++'ta terel deiklenler bloun herhangi bir yerinde bildirilebilir. Bir deikenin kullanma yakn bir blgede bildirilmesi C++ tasarmclarna gre daha okunabilirdir. (Deiken kavram nesne isimlerini, struct, union ve enum isimlerini ve enum sabitlerini, typedef isimlerini ieren genel bir terimdir.) O halde C++'ta yerel deikenin faaliyet alan bildirim noktasndan blok sonuna kadar olan blgeyi kapsar. Ne olursa olsun bir blok ierisinde ayn isimli birden fazla deiken bildirimi yaplamaz. C++da for dngsnn birinci ksmnda bildirim yaplabilir. rnek olarak: for(int i = 0,j = 20; i + j < 50; ...){ } Tabii while dngsnn ve if deyiminin ierisinde bildirim yaplamaz. #include <stdio.h> #define SIZE 100 void main(void) { for(int i = 0; i < SIZE; ++i) printf("%d\n", i); } Byle for dngsnn ierisinde bildirilmi deikenlerin faaliyet alanlar bildirildii yerden for dngsnn iinde bulunduu bloun sonuna kadar etkilidir. if, for, switch, while gibi deyimlerden sonra blok almam olsa bile gizli bir bloun ald dnlmelidir. { for (int i = 0; i < 100; ++i) { for (int j = 0; j < 100; ++j) { } printf(%d\n, j); /*geerli*/ } printf(%d\n ,i); /*geerli*/ printf(%d\n, j); /*geersiz*/ } { for (int i = 0; i < 100; ++i) for (int j = 0; j < 100; ++j) { } j = 10; /*geersiz*/ i = 10; /*geerli*/ }
2

2-)

C++ta // ile satr sonuna kadar yorumlama yaplabilir.

C++ta /* */ yorumlama biiminin yan sra kolaylk olsun diye // ile satr sonuna kadar yorumlama biimi de eklenmitir. Son senelerde byle bir yorumlama biimi standart Cde de kullanlmaya balanmtr. Ancak ANSI C standartlarnda tanml deildir. Tanabilirlik bakmndan bu yorumlama biimini standart Cde kullanmak tavsiye edilmez. 3-)C++ta arlan fonksiyon eer aran fonksiyonun yukarsnda tanmlanmamsa fonksiyon prototipi zorunludur. C de bir fonksiyonun arldn gren derleyici fonksiyonun arlma noktasna kadar fonksiyonun tanmlamasyla ya da prototipi ile karlamamsa geri dn deerini int olarak varsayar ve kod retir. Dolaysyla aadaki rnek Cde geerlidir.

void main(void) { int x; x = fonk(); } int fonk() { } Oysa C++ta derleyicinin arlma noktasna kadar fonksiyonun tanmlamasyla ya da prototipiyle karlamas gerekir. Dolaysyla yukardaki kod C++ta errordr. (NOT: CV++ ve nesne ynelimli programlama teknii bug oluturabilecek kodlardan kanlmas temeline dayandrlmtr. Yani garanti yntemler kullanlmaldr. Bu sebeple Cdeki pek ok uyar C++ta errore dntrlmtr.) 4-) C++ta farkl parametre yaplarna sahip ayn isimli birden fazla fonksiyon tanmlanabilir. void fonk(void) { } void fonk(int x) { } Cde ne olursa olsun ayn isimli birden fazla fonksiyon tanmlanamaz. Oysa
3

/*Bu durum Cde sorun olmaz ama C++ta error verir.*/

C++ta parametre yaps sayca ve/veya trce farkl olan ayn isimli birden fazla fonksiyon tanmlanabilir. Ayn isimli birden fazla fonksiyon varsa ve o fonksiyon arlmsa gerekte hangi fonksiyon arlm olduu arlma ifadesindeki parametre yaps incelenerek belirlenir. Yani arlma ifadesindeki parametre says ve tr hangisine uygunsa o arlm olur. Geri dn deerinin farkl olmas ayn isimli fonksiyon yazmak iin yeterli deildir. Yani geri dn deerleri farkl fakat parametre yaps ayn olan birden fazla fonksiyon tanmlanamaz. #include <stdio.h> void fonk(int x) { printf("int = %d\n", x); } void fonk(long x) { printf("long = %ld\n", x); } void fonk(void) { printf("void\n"); } void fonk(char *str) { puts(str); } void main(void) { fonk(); /*parametresi void olan fonksiyonu arr*/ fonk(10); /*parametresi int olan fonksiyonu arr*/ fonk(100L); /*parametresi long olan fonksiyonu arr*/ fonk(merhaba); /*parametresi karakter trnden gsterici fonksiyonu arr*/ } K ANLAMLILIK HATASI C++ta pek ok durumda derleyicinin birden ok seenek arasnda karar verememesinden dolay error durumuyla karlalr. Bu tr hatalara iki anlamllk hatalar denir. Yukardaki rnekte fonk(3.2); gibi bir arma yaplrsa Ambiguity between 'fonk(int)' and 'fonk(long)' hatasn verir. Ayn isimli birden fazla fonksiyon arasnda seme ilemi ancak parametre saylar alma ifadesine uygun birden fazla fonksiyon varsa gerekleir. Parametre says arlma ifadesine uygun tek bir fonksiyon varsa bu durumda tr uyumasna baklmaz. Cde olduu gibi otomatik tr
4

olan

dntrmesi yaplarak o fonksiyon arlr. C++ derleyicisi ayn sayda parametrelere sahip birden fazla ayn isimli fonksiyonun bulunmas durumunda arlma ifadesine tr bakmndan uygun bir fonksiyon bulamazsa bu durum iki anlamllk hatasna yol aar. Bu durumun 3 istisnas vardr: 1. Fonksiyon char ya da short parametreyle arlmsa char ya da short int parametreye sahip bir fonksiyon yok ancak int parametreye sahip bir fonksiyon varsa int parametreye sahip olan fonksiyon arlr. 2. Fonksiyon float parametreyle arlmsa ancak float parametreye sahip bir fonksiyon yok double parametreye sahip bir fonksiyon tanmlanmsa bu durumda double parametreye sahip olan fonksiyon arlr. 3. Fonksiyon ayn trden const olmayan bir ifadeyle arlmsa ancak ayn trden const parametreye sahip bir fonksiyon y,tanmlanmsa tr uyuumunun saland kabul edilir ve const parametreye sahip olan fonksiyon arlr. Cde ve C++ta tanmlanan ve arlan bir fonksiyon ismi .obj modl ierisine yazlmak zorundadr. .obj modl standardna gre ayn isimli birden ok fonksiyon modl ierisine yazlamaz. Standart C derleyicileri fonksiyon isimlerinin bana bir _ ekleyerek obj modln ierisine yazarlar. Oysa C++ derleyicileri fonksiyon isimlerini parametre trleriyle kombine ederek obj modl ierisine yazarlar. Bu durumda C++ta ayn isimli farkl parametrelere sahip fonksiyonlar sanki farkl isimlere sahiplermi gibi obj modle yazlrlar. 5-) extern C ve extern C++ bildirimleri C++ta normal olarak btn standart C fonksiyonlar arlabilir. Standart C fonksiyonlar lib dosyalarnn ierisine banda _ bulunarak yani standart C kurallaryla yazlmlardr. Oysa bu fonksiyonlarn C++tan arlmasyla bir uyumsuzluk ortaya kar. nk C++ derleyicisi arlan fonksiyonu obj modl ierisine bana _ koyarak deil parametre trleriyle kombine ederek yani C++ kurallaryla yazar. extern C bildirimi bir fonksiyonun prototipinin nne ya da bir fonksiyonun tanmlamasnn nne getirilirse /*rnein: extern C double sqrt(double); veya extern C void fonk(void) { ......... } */ derleyici bu fonksiyonu obj modl ierisine C kurallaryla yani bana _ koyarak yazar. Bylece Cde yazlm olan C++tan kullanlmas mmkn
5

Fonksiyon prototipleri

olur. Bir grup fonksiyon yazm kolayl salamak iin extern C blou iine alnabilir. extern C { void fonk(void); void sample(void); .... } Bloun ierisinde baka bildirimler ve kodlar bulunabilir. Ancak derleyici yalnzca bu bloun ierisindeki fonksiyonlarla ilgilenir. Bu durumda standart C balk dosyalarnn ierisinde fonksiyonlarn extern C bildirimiyle prototipleri yazlm olmas gerekir. Ayn dosya hem C hem C+ +ta include edilip kullanlabildiine gre ve extern C bildirimi sadece C+ + iin geerliyse bir problem ortaya kmaz m? Bu problem nceden tanmlanm cplusplus sembolik sabitiyle zmlenmitir: #ifdef cplusplus extern C { #endif ..... ..... ..... ..... ..... ..... #ifdef cplusplus } #endif Bir de extern C++ bildirimi vardr. Bu bildirim fonksiyon isimlerinin C++ kurallarna gre obj modln ierisine yazlacan anlatr. Zaten fonksiyonlar default olarak bu kurala gre yazlrlar. Bu bildirim ileriye doru uyumu salamak iin dnlmtr. u anda bir kullanm gerekesi yoktur. 6-) C++ta dinamik bellek ynetimi new ve delete isimli iki operatrle yaplr. Mademki C++ ierisinde btn standart C fonksiyonlar kullanlabiliyor, o halde dinamik bellek ynetimi malloc, claloc, realloc ve free fonksiyonlaryla yaplabilir. Ancak bu fonksiyonlar nesne ynelimli programlama tekniini uygulayabilmek iin tasarlanmamtr. Bu yzden C++ta yeni bir teknik kullanlmaktadr. C++ta dinamik olarak tahsis edilme potansiyelindeki bo blgelere free store denilmektedir(standart Cde heap denir). new Operatr Genel biimi:

new <tr> [<[uzunluk]>] new int new char new double [10] new float[n] new char[strlen(s) + 1] Eer keli parantez olmadan sadece tr ismi ile tahsisat yaplrsa o trden bir elemanlk yer tahsis edilmi olur. rnein: new int 1 intlik yer tahsis edilmitir. Eer keli parantez ierisine ifade yazlarak kullanlrsa bu durumda o ifade ile belirtilen sayda elemanlk alan tahsis edilir. new operatr tr belirli bir alan tahsis eder. Yani new operatryle elde edilen adresin tr bileeni arlma ifadesindeki tr ile ayn olur. int *p; p = new int; /* Burada sizeof(int) kadar byte tahsis ediliyor ve tahsis edilen */ /* alann balang adresi elde ediliyor. Bu adres int trndedndir. */ char *p; p = new int [10]; /* C++ta hatadr. */ p = (char *)new int[10]; /* Hata deil. */ /*----------new1.cpp---------*/ #include <stdio.h> #include <string.h> void main(void) { char *p; p = new char[30]; gets(p); puts(p); } /*------------------------------*/ New bir operatrdr. Ancak derleyici bu operatr kullanldnda dinamik tahsisat ileminin yaplmasn salamak iin dinamik tahsisat yapan bir fonksiyonun arma kodunu ama koda ekler. Yani new bir operatr olmasna karn tahsisat ilemi yerletirilen bu fonksiyon sayesinde programn alma zaman srasnda yaplmaktadr. Bu operatr ncelik tablosunun ikinci dzeyinde bulunmaktadr. rnein: new int + n gibi bir ilem geerlidir. lemler: lem 1 : new int
7

lem 2 : lem 1 + n New operatr tahsisat ilemini yapamazsa 0 deerini(NULL gsterici) retir. /*-------freestor.cpp------*/ /*free store alannn hesaplanmas*/ #include <stdio.h> #define BLOCKSIZE void main(void) { long size = 0; char *p; for(;;){ p = new char[BLOCKSIZE]; if(p == NULL) break; size += BLOCKSIZE; } printf("Free store size = %ld\n", size); } /*---------------------------*/ Keli parantez ierisine yazlan ifade sabit ifadesi olmak zorunda deildir. /*-----------new2.cpp---------*/ /*Tam olarak ad sosay uzunluu kadar bellek tahsis eden fonksiyonun kullanl*/ #include <stdio.h> #include <stdlib.h> char *getname(void) { char *p; char buf[80]; printf("Ad Soyad:); gets(buf); p = new char[strlen(buf) + 1)]; if(p == NULL){ printf("Cannot allocate memory..\n"); exit(1); } strcpy(p, buf); return p; } 1024

void main(void) { char *p; p = getname(); puts(p); } /*--------------------------------*/ delete OPERATR Delete operatr new operatryle tahsis edilmi olan bloklar serbest brakmak iin kullanlr. Genel biimi: 1. delete p; 2. delete [] p; Eer tahsisat tek para olarak yaplmsa yani keli parantez kullanlmadan yaplmsa silme ilemi keli parantez kullanlmadan yaplmaldr. rnein: int *p; p = new int; delete p; Eer tahsisat ilemi birden fazla eleman iin yaplmsa yani keli parantez kullanlarak yaplmsa serbest brakma ileminde de keli parantez kullanlmaldr. rnein: int *p; p = new int[n]; delete [] p; Burada keli parantez ierisine bir ey yazlmaz. delete operatr unary prefix bir operatrdr ve ncelik tablosunun ikinci dzeyinde bulunur. delete p + 1; /*Hatal*/ delete (p + 1);/*Doru*/ Delete operatrnn operand daha nce tahsis edilmi olan bloun balang adresi olmaldr. Deilse beklenmeyen sonular ortaya kabilir. Tabii derleici delete operatrne karlk ama koda (object modulee) free gibi tahsis edilmi blou serbest brakan bir fonksiyon kodu yerletirmektedir. new delete operatrlerinin tahsisat ilemlerinde kulland fonksiyon maloc, calloc, free fonksiyonlar olmak zorunda deildir. Bu iki grup fonksiyon farkl tahsisat tablolar kullanyor olabilir. Bu nedenle new delete operatrleriyle malloc, calloc, free gibi standart C fonksiyonlarn zel bir durum yoksa birlikte kullanmamak gerekir. nk bir grup tarafndan tahsis edilen alan dier grup tarafndan tahsis edilmemi gibi gzkebilir.
9

Grld gibi C++ta realloc fonksiyonun karl bir operatr yoktur. Ancak byle bir fonksiyon yazlabilir. /*------------realloc.cpp---------------*/ void *Realloc(void *ptr, size_t newsize, size_t oldsize) /*size_t unsigned int*/ { void temp; temp = new char [newsize]; memcpy(temp, ptr, oldsize); delete [] ptr; return temp; } /*----------------------------------------*/ Kullanm: p = new char [10]; p = Realloc(p, 20, 10); bytld */

/* /*

10 * sizeof(char) kadar bellek tahsis edildi */ Tahsis edilmi alan 20 * sizeof(char)e

set_new_handler FONKSYONU Normal olarak new oparetr baarszlkla sonulandnda 0 adresine geri dner ve bu adresin test edilmesi gerekir. Ancak her new kullanmnda bu adresin test edilmesi yerine daha etkin bir yntem kullanlmaktadr. new operatr baarsz olduunda set_new_handler fonksiyonu ile belirlenen fonksiyonu armaktadr. Bylece her defasnda kontrol yaplmasna gerek kalmaz. set_new_handler(void (*ptr)(void)); set_new_handlera parametre olarak geri dn deeri void parametresi void olan bir fonksiyonun adresi verilir. Artk baarszlk durumunda bu fonksiyon arlacaktr. new operatr baarszlk durumunda belirlenen fonksiyonu arr ve bu fonksiyon arldktan sonra tekrar tahsisat ilemini yapar. Yine baarsz olursa tekrar fonksiyonu arr ve bu byle devam eder. Yani aadaki algoritmadaki gib alr: for(;;){ if(boyer var m) return boyer; else set_new_handler(); } /*-----------snhandle.cpp---------------*/ #include <stdio.h> #include <new.h>
10

#include <stdlib.h> long size = 0; void myhandler(void) { printf("Free store size=%ld\n", size); exit(1); } void main(void) { void *ptr; void *oldhandler; oldhandler = set_new_handler(myhandler); for(;;){ ptr = new char [1024]; size += 1024; } } sen_new_handler(oldhandle);/*handler eski haline dntrld*/ /*------------------------------------------*/ set_new_handlern prototipi new.h iindedir. 7-) Bir adresin farkl trden bir gstericiye atanmas ve adres olmayan bir bilginin bir gstericiye atanmas durumu uyar deil error olarak deerlendirilir. Adres ilemlerinde tr uyumazlklar C++ta eror olarak deerlendirilir. Oysa standart C derleyicileri byle durumlarda en fazla uyar verirler. Ancak void gstericiye herhangi bir trden adres atanabilir. Fakat void bi adresin herhangi bir gstericiye atanmas error olarak deerlendirlir(bu durum Cde en fazla uyar olaak deerlendilir). Tabii tr dntrme operatryle her tr her tre atanabilir. /*----------fark7.cpp----------*/ void main(void) { int s[100]; char *t; t = s; */ t = (char *)s; /* Cannot convert 'int *' to 'char *' hatasn verir */

/* Hata vermez } /*--------------------------------*/

Benzer biimde const bir deikenin adresi ancak const bir gstericiye
11

atanmaldr. const int x; int *y; conts int *p; y= &x; /* p = &x; /*

Hata verir Hata vermez

*/ */

8-) const bildirimi ile yaratlm bir deiken sabit ifadesi gibi ilem grr. C++ta const bir deiken iin yine bellekte yer ayrlr. Ancak const deiken kullanldnda derleyici eer const deikene ilk deer sabit ifadesiyle verildiyse derleyici dorudan o sabit ifadesini kullanr. Tabii const deikene verilen ilk deer sabit ifadesi deilse bu consta deiken kullanldnda derleyici dorudan bir say yerletiremez, const deikenin kendisini yerletirir. const int MAX = a + 100; const int MIN = 1; y = MAX; /* y = MIN; /* const int SIZE = 10; int a[SIZE]; /*

Burada bir say yazamaz Burada MIN yerine 1 yazlabilir C++ta geerli Cde geerli deil

*/ */ */

Const deiken iin yine de bellkte yer ayrlr. Bu durumda const deikenin adresi alnabilir. Bu yolla const deikenin ierii de deitirilebilir. Tabii bu deitirme programn alma zaman ierisinde olduundan sonucu deitirmez. /*----------fark8.cpp------------*/ #include <stdio.h> void main(void) { const int SIZE = 10; int *p; p = (int *)&SIZE; *p = 20; printf("%d\n", SIZE); } /*--------------------------------*/ 9-) C++ta statik mrl deikenlere sabit ifadesiyle ilk deer verme zorunluluu yoktur. Global deikenler ve statik yerel deikenler gibi statik mrl deikenlere ilk deer Cde sabit ifadesiyle verilmek zorundadr. nk statik mrl deikenler ama kod ierisine ilk deerleriyle yazlrlar. Exe dosyasnn ierisinde yer alrlar. Bunun mmkn olabilmesi iin verilen ilk
12

deerlerin derleme aamasnda belirlenmi olmas gerekir. Derleme aamasnda tespit edilmesi iin ifadenin sabit ifadesi olmas gerekir. Oysa C++ta statik mrl deikenlere her trden sradan bir ifadeyle ilk deer verilebilir. Bu deikenler 0 ilk deeriyle ama koda yazlrlar. Programn alma zaman srasnda ve main fonksiyonundan nce ilk deerini alrlar. 10-) Parametre deikenlerinin default deerler almas(default function arguments) C++ta fonksiyon arlrken bir parametre belirtilmemise ona ilikin parametre deikeni default bir deer alabilir. Byle bir durum Cde yoktur. Bir parametre deikeninin default deer almas durumu fonksiyon tanmlanrken ya da prototip bildiriminde paramere deikeninden sonra eittir operatryle belirtilmelidir. /*---------fark10.cpp----------*/ #include <stdio.h> void fonk(int x = 10, int y = 20) { printf("x = %d y = %d\n", x ,y); } void main(void) { fonk(100, 200); /* x = 100 fonk(100); /* x = 100 fonk(); /* x = 10 } /*--------------------------------*/

y = 200 y = 20 y = 20

*/ */ */

Bir parametre deikeni default deer almsa onun sanda bulunanlarn hepsi default deerler almak zorundadr. void fonk(int x = 10, int y) { } void fonk(int x, int y = 20) { } /* Hata verir */

/*

Hata vermez */

Default deer almam olan btn parametre deikenleri iin arlma ifadesinde parametre yazlmak zorundadr. Default deer alan parametre deikenlerine sahip fonksiyonlarla ayn isimli baka fonksiyonlarn birlikte bulunmas durumunda iki anlamllk hatalar oluabilir. ki anlamllk hatalar fonksiyonlarn tanmlanmas sonucunda deil arlmas sonucunda ortaya kmaktadr. /* ki anlamllk hatas rnei */
13

#include <stdio.h> void fonk(int x, int y = 20) { printf("%d %d\n", x, y); } void fonk(int x) { printf("%d\n", x); } void main(void) { fonk(100, 200); /* Hata vermez */ fonk(100); /* ki anlamllk hatas verir } /*------------------------------------------*/ Bir gsterici parametresi de default deer alabilir. /* Gstericiye default deer #include <stdio.h> void message(const char *p = "Success") { puts(p); } void main(void) { char *p = "Ali"; message(p); message(); } /*-------------------------------------------*/ Default Parametre Kullanlma Nedenleri Deikenlerine Sahip Fonksiyonlarn */

*/

ok sayda parametrelere sahip fonksiyonlar sz konusu ise ve bu parametre deikenlerinin belli blmne arma srasnda ayn deerler atanyorsa default parametre deikenlerinin kullanlmas byk bir yazm kolayl salar. Fazla sayda parametrenin yazlmamas hem programcnn i ykn azaltr, hem de okunabilirlii arttrr. #include <stdio.h> #include <stdlib.h> void *myitoa(int n, char *str, int base = 10)
14

{ return itoa(n, str, base); } void main(void) { char s[100]; myitoa(123, s); puts(s); } Default deer alan parametre deikeni kullanlrken dikkat etmek gerekir. Bir fonksiyon % 90 ayn parametre deerleriyle arlyorsa default parametre deikeni kullanlmaldr. Hibir deer almayacana bari u deeri alsn fikriyle kullanlmamaldr. Bylesi kullanmlar kodu inceleyen kiiyi yanltrlar. Bazen parametre deikenine verilen default deerin zel bir anlam olmaz. Bu default deer fonksiyonun default parametreyle arlp arlmadn tespit etmek amacyla kullanlr. Gerek default deerler fonksiyonun ierisinde ve bir dizi ilemlerle elde edilir. rnein #define DEFAULT_CALL (-1)

void writefile(void *ptr, unsigned size, long offset = DEFAULT_CALL) { if(offset != DEFAULT_CALL) fseek(fp, offset, SEEK_SET); fwrite(ptr, 1, size, fp); } void main(void) { double x = 10.2; writefile(&x, sizeof(double)); } Default Deer Alan Fonksiyonlarn Prototipleri Parametre Deikenlerine Sahip

Byle fonksiyonlarn prototiplerinde dafault parametre deerleri belirtilmelidir. Prototip yazma ilemi deiken isimlerini kullanarak ya da kullanmayarak yaplabilir. rnein aadaki iki prototip de geerlidir. void sample(int = 10, int = 20); void sample(int a = 10, int b = 20); Prototipi yazlan fonksiyon ayn modl ierisinde tanmlanyorsa(yani ktphane ierisinde deilse) tanmlama srasnda bir daha bu default deerler yazlamaz. Yani default deerler ya prototipte ya da tanmlama
15

srasnda belirtilmek zorundadr. Her ikisinde birden belirtilemezler. Tavsiye ediln kullanm prototipte belirtilmesi, tanmlama da belirtilmemesidir. void sample(int x = 10, int y = 20); void sample(int x =10, int y = 20) /* { } void sample(int x, int y) { } /* Hata verir */

Hata vermez */

11-)C++ta gstericilere benzeyen ve ismine referans denilen ayr bir tr vardr. Referans Trnden Bir Gstericinin Tanmlanmas Genel biimi: <tr> &<referans_ismi> = <nesne> rnek: int a = 10; int &b = a; double x; .......... double &y = x; Bir referans ilk deer verilerek tanmlanmak zorundadr. rnein: int &r; double &r = 10.2; /* /* hata hata */ */

Referansa verilen ilk deer ayn trden bir nesne olmak zorundadr. double x = 10 ; int &r = x; /* int &r = a; /* Hata. Farkl trden bir nesneyle ilk deer verilmi. Okunuu: r int trnden bir referanstr */ */

Referanslar bir eit dzeyi yksek gstericidir. Referanslarn ierisinde adres bilgisi bulunur. Derleyici bir referans tanmlandnda ilk deer olarak verilen nesnenin adresini referansn ierisine yerletirir. Referanslar iyi anlayabilmek iin onlarn edeer gsterici karlklarn dnmek gerekir. E deer gsterici karl referans yerine gsterici kullanldnda
16

elde edilecek e deer kod anlamna gelir. int a = 10; int &b = a; Edeer karl: int a = 10; int *b = &a; Bir referans ilk deer verildikten sonra kullanldnda artk referans ierisindeki adres deil referans ierisindeki adreste bulunan bilgi temsil edilir.

/*----------fark11.cpp--------------*/ #include <stdio.h> #if 1 void main(void) { int a = 10; int &b = a; b = 50; printf("%d %d\n", b, a); } #endif #if 0 void main(void) { int a = 10; int *b = &a; *b = 50; printf("%d %d\n", *b, a); } #endif /*-------------------------------------*/ /* referansn gsterici karl */ /* referans kullanm */

17

int a = 10; int &b = &a; */

/*

Hata: &a int trnden deil adres trndendir

Referanslarn Fonksiyon Parametresi Olarak Kullanlmas Referanslar fonksiyon parametresi olarak kullanlabilirler. Madem ki bir referans ayn trden bir nesneyle ilk deer verilerek tanmlanmak zorundadr, o halde parametresi referans olan fonksiyonlar ayn trden bir nesnenin kendisiyle arlmak zorundadr. /* fonksiyon parametresi olan referans rnei */

#include <stdio.h> #if 1 /* parametresi referans */ void fonk(int &a) { a = 20; } void main(void) { int x = 10; fonk(x); printf("%d\n", x); } #endif #if 0 /* gsterici karl */ void fonk(int *a) { *a = 20; } void main(void) { int x = 10; fonk(&x); printf("%d\n", x); } #endif /*------------------------------------------------------------*/ Bir C programnda fonk(a) gibi bir arma ilemiyle a deitirilemez. Oysa C++ta byle bir arma fonksiyonun parametre deikeni bir referans ise a paametresini deitirebilir. Klasik bir C bak asyla parametre olan ann deitirilmeyecei sanlabilir. Okunabilirlii kuvvetlendirmek iin eer
18

parametreyi deitirecek bir fonksiyon tasarlanacaksa bunun iin referans deil gsterici kullanlmaldr. Fonksiyonun parametre deikeni referans ise derleyici tarafndan otomatik olarak yaplan bir adres aktarm sz konusudur. Referans uygulamas int a = 10; int &r1 = a; int &r2 = r1; r2 = 20; printf(%d\n, r1); Gsterici edeeri int a = 10; int *r1 = &a; int r2 = &r1; *r2 = 20; printf(%d\n, *r1);

/*-----referans.cpp-----*/ #include <stdio.h> #if 1 /* referans rnei void main(void) { int a = 10; int &a1 = a; int &a2 = a1; a2 = 20; printf("%d\n", a1); } #endif #if 0 /*gsterici edeeri void main(void) { int a = 10; int *a1 = &a; int *a2 = a1; *a2 = 20; printf("%d\n", *a1); } #endif /*-------------------------*/ /*-----referan1.cpp-----*/ #include <stdio.h> void main(void)
19

*/

*/

{ int a = 10; int &b = a; printf("%p %p\n", &a, &b); } /*--------------------------*/ Bir referans & operatryle adres alma ilemine sokulabilir. Bu durumda elde edilen deer referans ierisinde bulunan adreste bulunan nesnenin adresidir. Bu da referans ierisindeki adresle ayn olmak zorundadr. Bir referansn da bir adresi vardr. Ama o adres deeri geerli bir ifdade ile elde edilemez. r bir referans olmak zere & &r; ifadesi geerli deildir. nk bu ifadenin edeer gsterici karl & &*p;dir ve &*p bir nesne deildir. Yap Deikenlerinin Referans Yoluyla Fonksiyonlara Geirilmesi Bir yap deikeninin fonksiyona aktarlmasnda doru teknik yap deikeninin adresinin fonksiyona geirilmesidir. Yani fonksiyon yap deikeninin adresiyle arlr, fonksiyonun parametre deikeni o yap trnden bir gsterici olur. Fonksiyonun ierisinde elemana ok(->) operatryle eriilir. Ancak C++ta ayn etkinlikte olmak zere referansla aktarm da sz konusudur. Yani fonksiyon yap deikeninin kendisiyle arlr. Fonksiyonun parametre deikeni o yap trnden bir referans olur. Fonksiyon ieriisnde elemana nokta operatryle eriilir. /*----------referan2.cpp-------------*/ #include <stdio.h> struct PERSON{ char *name; int no; }; void disp(struct PERSON &r) { printf("%s %d\n", r.name, r.no); } void main(void) { struct PERSON per = {"Ali Sere", 123}; disp(per); } /*--------------------------------------*/

20

Yaplarn referans ya da gsterici yoluyla fonksiyonlara aktarlmas tamamen edeer kullanmlardr. const Referanslar Bir referans da const olarak tanmlanabilir. Referans rnei int a = 10; const int &b = a; b = 20; /* Hata */ Gsterici edeeri int a = 10; const int *p = &a; *p = 20; /* Hata */

Const bir referans, gsterdii yer const olan const bir gstericiye edeerdir. Yani byle referanslar sol tarafa deeri olarak kullanlamaz. nk referans ierisinde bulunan adresteki bilgi const yaplmtr. Const referanslar da okunabilirlii arttrmak amacyla fonksiyon parametresi olarak kullanlrlar. void disp(const struct PERSON &r); Fonksiyonun referans olan parametresi de default argman alabilir. int x; void fonk(int &a = x) deer alm*/ { ... } char &a = Ali; /* /*fonksiyonun referans olan parametresi default

Doru bir kullanmdr

*/

Fonksiyonun Geri Dn Deerinin Referans Olma Durumu Return ifadesiyle geri dn deerinin oluturulmas aslnda derleyici tarafndan tahsis edilen geici bir blgeye yaplan atama ilemidir. Yani return ifadesi nce geici bir blgeye yerletirilir, sonra oradan alnarak kullanlr. Fonksiyonun geri dn deerinin tr bu geici blgenin trdr. Bir fonksiyonun geri dn deeri referans olabilir. Bu durumda fonksiyonun geri dn deerine ilikin geici blge referans trndendir. Bir referansa bir nesneyle ilk deer verileceine gre byle fonksiyonlar return ifadelerinin de nesne olmas gerekir. Gsterici edeeri /*-----referan3.cpp-----*/ #include <stdio.h> int a = 10; Referans rnei /*------referan4.cpp-----*/ #include <stdio.h> int a = 10;

21

int *fonk(void) { return &a; } void main(void) { *fonk() = 20; printf("%d\n", a); }

int &fonk(void) { return a; } void main(void) { fonk() = 20; printf("%d\n", a); }

Artk bu fonksiyon kullanldnda referans kullanlyor gibi ilem greceinden return ifadesindeki nesne anlalr. Byle fonksiyonlarn geri dn deeri nesne belirtir ve sol taraf deeri olarak kullanlabilir. zetle referansa geri dnen bir fonksiyonun geri dn deeri kullanldnda return ifadesindeki nesnenin kullanld anlalr. Bir Referansa Farkl Bir Trden Bir Nesneyle lk Deer Verilmesi Durumu Byle bir durumda nce referansla ayn trden geici bir deiken yaratlr. Verilen ilk deeri bu geici deikene atar, tabii otomatik tr dntrlmesi olur ve yaratlan bu geici blgenin adresi referansa aktarlr. /*-----referan5.cpp-----*/ #include <stdio.h> void main(void) { double x = 3.2; int &r = x; r = 5; printf("%f\n", x); } /*--------------------------*/ Tabii bylesi bir durumda derleyiciler bir uyaryla durumu bildirirler. Bir Referansa Sabitle lk Deer Verilmesi Durumu Bir referansa bir sa taraf deeriyle de ilk deer verilebilir. Bu durumda ilk deer olarak verilen sa taraf deeri derleyici tarafndan oluturulan geici bir blgenin ierisine aktarlr. Geici blgenin adresi de referansa yerletirilir. /* /* /* /* Edeeri double x =3.2; int temp = x; int &r = temp; */ */ */ */

22

Referans rnei /*-----referan6.cpp-----*/ #include <stdio.h> void main(void) { int &r = 10; r = 50; printf("%d\n", r); }

Edeeri int temp; int &r = temp;

Byle iki problemli ilk deer verme durumlarndan da kanmak gerekir. Her iki durumda da derleyici uyar mesaj verecektir. Gstericilerle Referanslar Arasndaki Benzerlikler ve Farkllklar Gstericiler de referanslar da adres tutan nesnelerdir. Referansn ierisindeki adres bir daha deitirilemez ama gstericinin ierisindeki adres deitirilebilir. Diziler tr ne olursa olsun, referans yoluyla referanslara geirilemezler. nk dizi elemanlarna erimek iin adres arttrm yapmak gerekir. Referanslar tek bir eleman fonksiyona geirmek iin kullanlabilirler.

12-)Cde enum tr ile int tr tamamen ayndr. Yani enum trnden bir deikene int trnden bir deer atanabilir. Oysa C++ta enum tr ayr bir trdr ve enum trnden deikenlere ancak enum trnden sabitler atanabilir. SINIFLAR(classes) Snflar nesne ynelimli programlama tekniini uygulayabilmek iin mutlaka gerekli olan Cdeki yaplara benzeyen C++a zg veri yaplardr. Tpk yaplarda olduu gibi snflarla da almadan nce bir snf bildirimi yapmak gerekir. Snf bildirimi bellekte yer kaplamaz(C++ta nesne terimi daha ok bir snf trnden deikeni anlatmakta kullanlr. Nesne ynelimli programlama teknii snflar kullanlarak program yazma tekniidir). Snf Bildiriminin Genel Biimi: class [snf_ismi] { [private:] ... ... [protected:] ...
23

... [public:] ... ... }; Bir snf 3 blmden oluur: 1. Private 2. Protected 3. Public Bir blm blm belirten anahtar szck ve iki nokta st ste ile balatlr, baka bir blm belirten szce kadar srer. Birden fazla ayn blm belirten anahtar szck ayn snf bildirimi ierisinde kullanlabilir. Blm belirten anahtar szcklerin biri ya da hibirisi yazlmak zorunda deildir. Snf hibir blm belirten anahtar szckle balatlmamsa private blm anlalr. Okunabilirlik asndan snf isminin ilk harfi byk geri kalan harfleri kk yazlr. Bir yap yalnzca veri elemanlarna sahiptir. Snflar hem veri hem fonksiyon ieren veri yaplardr. Yani normal yaplardan snflarn fazlalklar ayn zamanda fonksiyon da iermeleridir. Snf ierisinde bildirilen deikenlere snfn veri elemanlar(data member) snf ierisinde bildirilen fonksiyonlara ise snfn ye fonksiyonlar(member function) denir(daha yksek seviyeli nesne ynelimli dilllerinde metod ismi de kullanlr). Veri elemanlar ve ye fonksiyonlar snfn herhangi bir yerinde yazlabilir. ye fonksiyonlarn sadece prototipleri snf ierisine konur. Tanmlamalar snf bildiriminden sonra yaplr. Ancak genellikle protected blm pek kullanlmaz, snfn veri elemanlar private blme ye fonksiyonlar public blme yazlr. Bir Snf Trnden Nesnenin Tanmlanmas Genel biimi: [class] <snf_ismi> <nesne_ismi>; class Sample x; Sample y; Class anahtar szc yazlmayabilir. C++ta yap trnden nesne tanmlarken struct anahtar szc de kullanlmayabilir. Bir snf nesnesi iin snfn toplam veri elemanlar kadar yer ayrlr. /*-----class1.cpp-----*/ #include <stdio.h> class Sample { private: int a, b; public: void fonk(void);
24

}; void main(void) { Sample x; printf("%d\n", sizeof(x)); } /*-----------------------*/ ye Fonksiyonlar Tanmlanmas ye fonksiyonlar prototipleri snf bildirimi tanmlamalar darda aadaki gibi yaplr. [geri dn deerinin ([parametreler]) void Sample::fonk(void) { } ki tane iki nokta stste C++a zg bir operatrdr. ye fonksiyonlar ama koda parametre trleri ve snf isimleriyle kombine edilerek yazlrlar. Yani ayn isimli ve ayn parametre yapsna sahip bir ye fonksiyonu ve global bir fonksiyon tanmlanabilir. Hibir snfa ait olmayan fonksiyonlara global fonksiyon denir. Snfn Veri Elemanlarna ve ye Fonksiyonlarna Eriim Snfn veri elemanlarna ve ye fonksiyonlarna nokta operatryle eriilir. Bir ye fonksiyonu ancak ayn snf trnden bir nesneyle arlabilir. Eer nesne olmadan arlrsa global bir fonksiyonun arld anlalr. X.fonk(); fonk(); /*ye fonksiyonu arlm*/ /*global fonkiyon arlm*/ tr] <snf isim> ierisine :: yerletirilir, ismi>

<fonksiyon

/*-----class2.cpp-----*/ #include <stdio.h> class Sample { public: int a, b; public: void fonk(void); }; void Sample::fonk(void) { printf("I'm sample fonk..\n");
25

} void fonk(void) { printf("I'm global fonk..\n"); } void main(void) { class Sample X; X.a = 10; X.b = 20; X.fonk(); fonk(); } /*-----------------------*/ Bir ye fonksiyon ierisinde snfn hangi blmnde tanmlanm olursa olsun btn veri elemanlar ve ye fonksiyonlarna dorudan eriilebilir. Yani snfn veri elemanlar snfn ye fonksiyonlar arasnda ortak olarak kullanlmaktadr. Bir ye fonksiyon ierisinde kullanlan ye fonksiyonlar o ye fonksiyon hangi snf nesnesiyle arlmsa o snf nesnesinin elemanlar olur. /*-----class3.cpp-----*/ #include <stdio.h> class Sample { public: int a; public: void fonk1(int x); void fonk2(void); }; void Sample::fonk1(int x) { printf("I'm sample fonk1..\n"); a = x; } void Sample::fonk2(void) { printf("%d\n", a); } void main(void) { class Sample X; X.fonk1(50);
26

Sample Y; Y.fonk1(100); X.fonk2(); Y.fonk2(); } /*-----------------------*/ Bir ye fonksiyonu ierisinde snfn bir dier ye fonksiyonu da dorudan arlabilir. Snfn a ye fonksiyonu X nesnesiyle arlm olsun, a ye fonksiyonu ierisinde b ye fonksiyonu dorudan arlabilir. Bu durumda b ye fonksiyonu ierisinde kullanlan veri elemanlar X snf nesnesine ilikindir. /*-----class4.cpp-----*/ #include <stdio.h> class Sample { public: int a; public: void fonk1(int x); void fonk2(void); }; void Sample::fonk1(int x) { printf("I'm sample fonk1..\n"); a = x; fonk2(); } void Sample::fonk2(void) { printf("%d\n", a); } void main(void) { class Sample X; X.fonk1(50); } /*-----------------------*/ Snf Faaliyet Alan(class scope) Cde dardan genie doru 3 tr faaliyet alan vardr: 1. Blok faaliyet alan
27

2. Fonksiyon faaliyet alan 3. Dosya faaliyet alan Cde ve C++ta ayn faaliyet alanna ilikin birden fazla deiken ayn isimle tanmlanamaz. Ancak farkl faaliyet alanna ilikin ayn isimli birden fazla deiken tanmlanabilir. Bir blok ierisinde birden fazla ayn isimli deiken faaliyet gsteriyorsa o blok ierisinde dar faaliyet alanna sahip olan eriilebilir. C++ta snf faaliyet alan diye isimlendirilen ayr bir faaliyet alan daha tanmlanmtr. Snf faaliyet alan fonksiyon faaliyet alan ile dosya faaliyet alan arasnda bir alana sahiptir. Snf faaliyet alan yalnzca bir snfn tm ye fonksiyonlar arasnda tannma araldr. Snfn veri elelamanlar ve ye fonksiyon isimleri snf faaliyet alanna uyarlar. Bir snfn veri elemanyla ayn isimli snfn ye fonksiyonu ierisinde ayn isimli bir yerel deiken tanmlanabilir. Bu durumda fonksiyon ierisindeki blokta yerel olana eriilir. Benzer biimde bir ye fonksiyon ierisinde bir fonksiyon arlmsa arlan fonksiyon ile ayn isimli hem global hem de bir ye fonksiyon varsa dar faaliyet alan kuralna gre ye fonksiyon arld varsaylr. znrlk Operatr(::)(scope resolution operator) :: operatrne znrlk operatr denir. Bu opertrn hem binary-infix hem de unary-prefix olarak kullanlan tipleri vardr. 1. Binay infix resolution operatr: Bu kullanmda sol tarafndaki operandn bir snf ismi, sa tarafndaki operandn ise veri eleman ya da fonksiyon ismi olmas gerekir. Bu operatr snfn faaliyet alan probleminden dolay gizlenmi olan veri elemanna ya da ye fonksiyonuna eriimini salar. void Sample::fonk1(int a) { printf(Sample fonk1..\n); Sample::a = a; parametre ay ata*/ }

/*snfn

veri

eleman

olan

aya

2. Unary prefix resolution operatr: Bu durumda operand global bir deiken ya da fonksiyon ismi olabilir. Bu haliyel bu operatr faaliyet alan probleminden dolay global olana eriimi salar. Bu operatr ncelik tablosunun en yksek dzeyinde bulunur. Balang ve Biti Fonksiyonlar 1. Balang Fonksiyonlar(constructors) Bir snf destesi tanmlandnda derleyici tarafndan otomatik olarak
28

arlan fonksiyona snfn balang fonksiyonu denir. Yerel bir snf nesnesi programn ak tanmlama noktasna geldiinde, global bir snf nesnesiyse program bellee yklenir yklenmez yaratlr. Balang fonksiyonun ismi snf ismiyle ayn olmaldr. Balang fonksiyonlarnn geri dn deeri gibi bir kavram yoktur. Yani geri dn tr yerine bir ey yazlmaz. bu durum int ya da void anlamna gelmez. Balang fonksiyonlar ierisinde return anahtar szc kullanlabilir, ancak yanna bir ifade yazlamaz. C++ta farkl parametre yapsna sahip birden fazla balang fonksiyonu olabilir. Parametresi olmayan(yani void olan) balang fonksiyonuna default balang fonksiyonu(default constructor) denir. Eer snf nesnesi nesne isminden sonra parantez almadan yani normal bir biimde tanmlanm ise (rnein: X n;) bu durumda varsaylan balang fonksiyonu arlr. Eer nesne isminden sonra bir parantez alr ve ierisine bir parametre listesi yazlrsa (rnein: X n(10);) parametre listesine uygun olan balang fonksiyonu arlr. Uyar: Nesne isminden sonra parantez alp iine hibirey yazlmazsa bu durumda varsaylan balang fonksiyonu arlmaz. Bu ifade bir fonksiyon prototipi anlamna gelir. rnein: X a(); /*parametresi olmayan, X trnden bir fonksiyonun prototipi*/ Global snf nesnelerine ait balang fonksiyonlar main fonksiyonundan nce arlr. Daha yukarda tanmlanan daha nce arlacak bir biimde sralama sz konusudur. 2. Biti Fonksiyonu(destructor) Bir nesne faaliyet alann bitirmesiyle bellekten silinir. Yerel deikenler programn ak tanmlandklar bloun sonunda, global deikenler ise programn bitimiyle bellekten silinirler. Bir snf nesnesi bellekten silinecei zaman otomatik olarak arlan fonksiyona biti fonksiyonu(destructor function) denir. Biti fonksiyonunun ismi snf ismiyle ayndr, anck bana bir ~ sembol getirilir. Biti fonksiyonunun da geri dn deeri gibi bir kavram yoktur. Biti fonksiyonu en az ve en fazla bir tane olabilir. Parametresi void olmak zorundadr. Yani parametresi olmamak zorundadr. Varsaylan biti fonksiyonu diye bir kavram yoktur. Global bir snf nesnesine ait biti fonksiyonu programn sonucunda main bittikten sonra yani mainin sonunda altrlr. Balang ve biti fonksiyonlarnn arlma sralar her zaman terstir. a ve b herhangi trden iki snf nesnesi olmak zere balang fonksiyonlar nce a sonra b olacak eklinde arlyorsa biti fonsiyonlar nce b sonra a eklinde arlr(LIFO sistemi). Balang ve Biti Fonksiyolarnn Bulundurulma Kural Snfn biti fonksiyonu olmak zorunda deildir. Yani varsa arlr yoksa arlmaz. Bir snf nesnesinin tanmlanma biimine uygun bir balang bir fonksiyonu olmak zorundadr. Ancak snfn hibir balang fonksiyonu yoksa ve nesne varsaylan balang fonksiyonu arlacak biimde tanmlanmsa bu durum istisna olarak hata oluturmaz. Ancak snfn
29

herhangi bir balang fonksiyonu varsa fakat varsaylan balang fonksiyonu yoksa varsaylan fonksiyonu aracak biimde yaplacak bir tanmlama hata ile sonulanr. Balang ve Biti Fonksiyonlarnn Kullanlma Nedenleri Nesne ynelimli programlama da bir snf belirli bir amac gerekletiren bir ktphane olarak ele alnabilir. rnein seri port ilemlerini yapan bir snf tasarlanabilir. Fare ilemleri iin ayr bir snf yazlabilir. Bu snflarn faydal ilemleri yapan bir takm ye fonksiyonlar olmaldr. Bu ye fonksiyonlar snfn veri elemanlarn ortak olarak kullanrlar. Bir snf bir takm yararl ileri yapmaya aday ise o yararl ilemleri gerekletirmek iin baz hazrlk ilemleri gerekebilir. rnein seri port ile ilgili ilem yapan bir snfta seri portun set edilmesi, fare ilemleri yapan snfta farenin reset edilmesi dosya ilemleri yapan bir snfta dosyann almas bu tr hazrlk ilemleridir. Bu hazrlk ilemleri snfn balang fonksiyonu ierisinde yaplrsa snf kullanan kod klr, ayrntlar gz ard edilir ve alglama iyiletirilir(abstraction). rnein dosya ilemleri yapan snfn balang fonksiyonu ierisinde dosya alabilir. Nesne tanmlanr tanmlanmaz hazrlk ilemlerinin otomatik olarak yaplmas snf kullanan kiilerin de ilerini kolaylatrr. Biti fonksiyonu balang fonksiyonuyla yaplan hazrlk ilemlerinin otomatik bir biimde geri alnmas iin kullanlr. rnein dosya ilemlerini yapan snfn biti fonksiyonu otomatik olarak kapayabilir. Seri port ilemlerini yapan snfn biti fonksiyonu port ayarlarn eski durumuna getirebilir. Tabii baz durumlarda hazrlk ilemlerinin geri alnmas gerekmeyebilir. Yani balang fonksiyonunun olmas biti fonksiyonunun olmasn mantksal bakmdan gerekli klmaz. Snflarda Temel Eriim Kurallar Temel eriim kural snf blmlerinin ne anlama geldiiyle ilgilidir. ki kural vardr: 1. Bir snf nesnesi yoluyla dardan nokta ya da ok operatrn kullanarak snfn yalnzca public blmnde bildirilen veri elemanlarna ya da fonksiyonlarna eriilebilir. Private veya protected blmlerine eriilemez. 2. Snfn ye fonksiyonu hangi blmde bildirilmi olursa olsun snfn her blmndeki veri elemanlarna ve ye fonksiyonlarna eriebilir. Yani ye fonksiyonlar ierisinde snfn her blmndeki veri elemanlarn kullanabilir ve ye fonksiyonlarn arabiliriz. Genellikle snfn veri elemanlar snfn rivate blmnde ye fonksiyonlar ise public blmde tutulur. Bylece veri elemanlarna dardan dorudan eriilemez. Dardan dorudan ye fonksiyonlara eriilir. ye fonksiyonlar veri elemanlarna eriirler. Yani veri elemanlarna dorudan deil ye fonksiyonlar yoluyla eriilmesi istenmitir. Eer private blgedeki veri elemanlarnn deerlerini almak ya da bunlara deer yerletirilmek istenirse bunlarla iliki kuran bir grup get ve set fonksiyonu yazmak
30

gerekir. Yeniden kullanlabilirlik(reusability) nesne ynelimli programlama tekniinin anahtar kavramlarndan birisidir. Bu kavram yazlm olan bir kodun zellikle de bir snfn baka projelerde tekrar yazlmadan kullanlmas anlamna gelir. Veri Elemanlarnn private, ye Fonksiyonlarnn public Ksmna Yazlmas Genellikle snflarda veri korumas istendii zaman snfn veri elemanlar private blgeye ye fonksiyonlar ise public blgeye yazlrlar. Snfn veri elemanlarnn private blgeye yerletirilmesi dardan onlara dorudan eriimi engeller. Onlara public blgedeki bir grup ye fonksiyon ile eriiriz. Normalde tasarlanm olan bir snf ok deiik ve uzun kodlarda kullanlabilir. Yani snf kullanan kodlar snfn kendi kodlarndan ok daha fazladr. Eer veri elemanlarn private blgeye yerletirirsek o veri elemanlarnn genel yapsnda deiiklik olduunda snf kullanan kodlar deitirmek zorunda kalmayz. Yalnzca prototipleri ayn kalmak zere snfn ye fonksiyonlarn yeniden yazmak zorunda kalrz. Oysa veri elemanlar public blgeye yerletirilseydi, dardan bu elemanlara dorudan eriilebilirdi ve veri yaps deitiinde onu kullanan tm kodlar deitirmek gerekirdi. eitli veri elemanlarn ve ye fonksiyonlar private blgeye yerletirmekle onlar snf kullanan kiinin algsndan uzak tutarz. Kiiler eriemeyecekleri bilgileri incelemezler. Bu durumda nesne ynelimli programlama tekniinde veri gizleme(data hiding) denir. Tabi veri elemanlarnn private blgeye yerletirilmesi bunlara eriimi zorlatrr. nk eriim dorudan deil, ara birim ye fonksiyonlarla yaplr. Snfn veri yaps deitirilmeyecekse veri elemanlar dorudan public blgeye de yerletirilebilir. Bu durumda onlar dorudan kullanmann bir zarar olmaz. /*----date2.cpp----*/ /*----date3.cpp----*/

Dinamik Tahsisat Yapan Snflar

Pek ok snf balang fonksiyonu ierisinde bir veri eleman iin dinamik tahsisat yapar. Tahsis edilen bu dinamik blgenin biti fonksiyonu ierisinde otomatik olarak sisteme iade edilmesi istenir. /*----consdest.cpp----*/ Bir dosyann balang fonksiyonu iinde almas ve biti fonksiyonunda otomatik olarak kapatlmas gibi durumlara ska rastlanr. /*----clasfile.cpp----*/ Bazen biti fonksiyonunda otomatik olarak yaplan geri alma ilemi bir ye fonksiyon ile bilinli olarak da yaplabilir. Bylece biti fonksiyonundaki geri alma ilemi geersiz hale gelir. nk geri alma ilemi daha nce geeklemitir. O halde biti fonksiyonu ierisinde geri alma ilemi daha
31

nce yaplmsa geri alma ilemini yapmamak gerekir. bunu salamak iin eitli veri elamanlarndan faydalanlabilir. File::File(void) { f = NULL; } File::~File(void) { if (f) fclose(f); } Snf Trnden Gstericiler ve Adresler Bir snf nesnesinin veri elamanlar tpk bir yap gibi bellee adrl bir biimde yerletirilir. Snfn ayn blmndeki veri elemanlar o blm ierisinde ilk yazlan dk anlaml adreste olacak biimde ardl olarak yerletirilirler. Ancak blmlerin sras iin herhangi bir zorunluluk standartlara konulmamtr. Yani blm ileri ilk yazlan dk anlaml adreste olacak biimde yerletirilir, ancak blmlerin kendi aralarnda nasl yerletirilecei derleyiciden derleyiciye deiebilir. Blmler aras yerleim de ardl olmak zorundadr. Ancak derleyicilerin hemen hepsi blm fark gzetmeksizin ilk yazlan elemann dk anlaml adreste olaca biimde yerleim kullanrlar. Bir snf nesnesinin adresi alnabilir. Elde edilen adresin saysal bileeni snf veri eleman blounun balang adresidir. Bir snf trnden deikenin adresi ayn trden bir snf gstericiye yerletirilmelidir. Bir snf gstericisi yoluyla snfa ilikin bir ye fonksiyon ok operatryle ya da * ve nokta operatryle arlabilir. Date x(10, 10, 1999); Date *p; p = &x; x.Disp(); /* p -> Disp(); /* (*p).Disp(); /* Disp() fonksiyonu arlr Disp() fonksiyonu arlr Disp() fonksiyonu arlr */ */ */

Bir ye fonksiyon snfa ilikin bir gsterici kullnlarak ok operatryle arldnda ye fonksiyon o gstericiyel belirtilen adreste bulunan veri elemanlarn kullanr. p -> Disp(); Disp() ye fonksiyonu p gstericisinin ierisinde bulunan veri elemanlarn kullanr. /*-----date4.cpp-----*/ Yine gsterici yoluyla snfn veri elemanlarna eriilir. Tabii bu elemanlarn public blgede olmas gerekir.
32

Snf Trnden Referanslar Bir snf trnden referans ayn trden bir snf nesnesiyle ilk deer verilerek tanmlanabilir. Bu durumda derleyici ilk deer olarak verilen snf nesnesinin adresini referansa yerletirir. Bir referans yoluyla snfn veri elemanlarna ve ye fonksiyonlaryla nokta operatr kullanlarak eriilir. Bir referans ile bir ye fonksiyonu arldnda ye fonksiyon referansn ierisinde bulunan adresteki veri elemanlarn kullanr. /*-----date5.cpp-----*/ Snf Trnden Deikenlerin Fonksiyonlara Geirilmesi Bir snf tpk yap gibi bileik bir nesnedir. Bu durumda yaplarda olduu gibi fonksiyona geirmede iki teknik kullanlabilir. Snfn kendisinin geirilmesi yntemi zel durumlar dnda kt bir tekniktir. Adres yntemiyle fonksiyona geirme teknii tercih edilmelidir. Adresle geirme ilemi C++ta iki biimde yaplabilir: 1. Gsterici kullanlarak: Yani fonksiyon bir snf nesnesinin adresiyle arlr. Fonksiyonun parametre deikeni de ayn snf trnden bir gsterici olur. Bu durumda fonksiyon ierisinde snfn veri elemanlarna ve ye fonksiyonlarna ok operatryle eriilir. /*-----date6.cpp-----*/ 2. Referans kullanlarak: Bu durumda fonksiyon bir snf nesnesinin kendisiyle arlr. Fonksiyonun parametre deikeni ayn trden bir referans olur. Fonksiyon ierisinde veri elemanlarna ve ye fonksiyonlarna nokta operatryle eriilir. /*-----date7.cpp-----*/ Bu iki yntem arasnda etkinlik fark yoktur. Date *p; p - > Disp(); fadesi syntax bakmndan geerlidir. Ancak bir gsterici hatas sz konusudur. Disp() fonksiyonu p gstericisinin ierisindeki rastgele yerdeki veri elemanlarn kullanr. Bir snf trnden referans ya da gsterici tamnmlandnda balang fonksiyonu arlmaz. nk balang fonksiyonu nesnenin kendisi tanmlandnda arlmaktadr. Snf Trnden Dinamik Alan Tahsis Edilmesi New operatryle bir snf trnden heap zerinde dinamik bir alan tahsis edilebilir. Tahsis edilen alann balang adresi ayn trden bir gstericiye atanmaldr. Madem ki new operatryle heap zerinde bir nesne yaratlyor o halde yaratlan nesne iin balang fonksiyonu arlr. Bir snf trnden dinamik alan tahsis edildiinde tahsis edilme ileminin hemen ardndan derleyici tarafndan otomatik olarak tahsis edilen alan iin
33

balang fonksiyonu arlr. Eer snf isminden sonra bir parantez almazsa varsaylan balang fonksiyonu, alr ve bir parametre listesi yazlrsa parametre listesine uygun olan balang fonksiyonu arlr. X *p; p = new X; /*default balang fonksiyonu arlr*/ p = new X(a, b, c); /*parametreleri uyan balang fonksiyonu arlr */ p = new X(); /*default balang fonksiyonu arlr */ /*-----date8.cpp-----*/ C++ta dinamik bellek ynetiminin dinamik bellek fonksiyonlaryla deil de new ve delete ile yaplmasnn nedeni balang fonksiyonunun otomatik olarak arlmasn salamak iindir. Snf Trnden Yaratlm Dinamik Bir Alann Boaltlmas Dinamik olarak tahsis edilmi bir snf delete operatryle sisteme iade edilebilir. delete operatr alan serbets brakmadan nce biti fonksiyonunu otomatik olarak armaktadr. /*-----date9.cpp-----*/ new operatryle bir snf trnden bir dizi alan tahsis edilebilir. p = new X[n]; Bu durumda derleyici n * sizeof(X) kadar alan dinamik olarak tahsis eder ve yaratlm olan n nesnenin her biri iin default balang fonksiyonunu arr. Bir dizi iin alan tahsis edilmesi durumunda tahsis edilen snf nesneleri iin baka bir balang fonksiyonu arlamaz. p = new X[n] (a, b, c); /*Geerli deildir. Tr dnm olarak dnlr*/ Ancak bir dizi snf nesnesi iin dinamik tahsisat ilemine ok nadir rastlanr. Bir dizi snf nesnesi iin tahsis edilmi olan alann delete ile silinmesi durumunda her bir snf nesnesi iin ayr ayr biti fonksiyonu arlr. Ble bir durumda eer yanllkla silme ilemi keli parantez kullanlmadan yaplrsa(rnein: delete p;) tm dinamik alan serbest braklr fakat yalnzca ilk yaratlm nesne iin biti fonksiyonu arlr. /*-----date10.cpp-----*/ Snf Trnden Dinamik Tahsisat leminin Anlam ve nemi class X { public: X(int n);
34

void Disp(void); private: int x; }; X:X(int n) { x=n; } void X::Disp(void) { printf(%d\n,x); } X::~X(void) { printf(I am a destructor\n); } X *p; void main (void) { { } } Normal bir snf nesnesi iin balang ve biti fonksiyonlarnn arlaca nokta, nesnenin tanmland yere gre belirlenmektedir. rnein yerel bir nesne iin biti fonksiyonu kesinlikle tanmlama blonun sonunda arlr. Oysa tahsisat ilemi dinamik olarak yaplrsa, nesnenin yaratlmas ve bellekten silinmesi, balang ve biti fonksiyonlarnn arlmas programcnn istedii noktada yaplabilir. Dinamik olarak tahsis edilmi snf nesnesi iin delete operatr ile silme yaplmamsa tahsis edilmi olan alan normal olarak programn bitiminde sisteme iade edilir. Ancak bu iade edilme ilemi srasnda biti fonksiyonu arlmaz. Dinamik olarak tahsis edilmi bir alan iin biti fonksiyonunun arlmas ancak delete ilemi ile mmkn olabilir. Snf nesnesi iin dinamik tahsisat yapld halde balang fonksiyonun arlmamas aadaki gibi salanabilir. p= (X *) new char [sizeof(X)] CONST ye fonksiyonlar Standart Cde bir fonksiyonun const olmas tanml ve geerli deildir. Oysa C++ds bir snfn ye fonksiyonu const olabilir. (C++da global bir
35

fonksiyon const olamaz, sadece snf ye fonksiyonlar const olabilir) Bir ye fonksiyonu const yapabilmek iin, fonksiyon prototipinde ve tanmlama srasnda parametre parantezi kapatldktan sonra const anahtar szc yazlmaldr. (Not const anahtar szcnn hem prototipte hem de tanmlama cmlesinde yazlmas zorunludur). Const ye fonksiyon ierisinde snfn ye elemanlar deitirilemez. Class X { public: X(int n); void set(int n); void Disp (void) const; ~X(void); private: int x; }; X::X(int n) { x=n; } void X::Disp(void) const { printf(%d\n,x); x=10; } X::~X(void) { printf(I am a destructor\n); } void main(void) { X a(20); a.disp(); }

//hata verecek

Const ye fonksiyonlar, const ye fonksiyonlarda olduu gibi okunabilirlii artrmak iin kullanlabilir. Class X { public: X(int n);
36

void set(int n); void Disp (void) const; ~X(void); private: int x; }; X::X(int n) { x=n; } void X::set(int n) { x=n; } void X::Disp(void) const { printf(%d\n,x); x=10; } X::~X(void) { printf(I am a destructor\n); } void main(void) { X a(20); a.disp(); a.set(50); a.disp(); }

//hata verecek

Const bir fonksiyon ierisinde const olmayan bir fonksiyon arlamaz, nk const olmayan bir fonksiyon snfn veri elemanlarn kullanabilir. Const bir ye fonksiyonun ierisinde snfn btn ye elemanlarnn const olduu kabul edilir. rnein byle bir ye fonksiyon ierisinde snfn bir veri elemannn adresi const olmayan bir gstericiye atanamaz. Not: C++da const bir deikenin adresi const olmayan bir gstericiye atanamaz. Snfn balang ve biti fonksiyonlar const ye fonksiyonu olarak tanmlanamaz. Yasak.

37

Const Snf Nesneleri void main(void) { const X a(10); } Bir snf nesnesi const olabilir. Bu durumda snf nesnesinin veri elemanlar her hangi bir biimde deitirilemez. Const bir snf nesnesi ile ancak const bir ye fonksiyon arlabilir, const olmayan bir ye fonksiyon arlamaz. Not: Const tamamen derleyici iin olan bir kavramdr. Const bir snf gstericisi ya da referans sz konusu olabilir. Tabii bu gsterici ya da referansla ancak const ye fonksiyonlar arlabilir. zellikle bir fonksiyonun parametre deikeninin const bir snf gstericisi ya da const bir snf referans olma durumuna sklkla rastlanr. String Snf Cde yazlar zerinde ilem yapmak iin karakter dizileri kullanlr. Ancak karakter dizilerinin normal bir dizi biiminde tanmlanmas genellikle kullanlan yntem olsa da nemli problemleri vardr. rnein dizinin uzunluu sabit ifadesi olmak zorundadr. Bylece yazlarn bytlmesi gibi ilemler verimsiz bir biimde yaplr. nk ilemler en kt olaslkla uzun diziler alarak yrtlmek zorundadr. Bu da bellein verimsiz kullanlmas anlamna gelir. Tabii dinamik bellek ynetimiyle yer kaplama bakmndan etkinlik problemi giderilebilir. Ancak ilemsel karmaklk artar, kod bymesi oluur. Ancak C++ta yaz ilemleri iin zel tasarlanm string snflar kullanlabilir. Bu snflar yazlar dinamik olarak saklarlar. Dinamik bellek ilemleri ye fonksiyonlar tarafndan otmatik olarak yapld iin alglsal dzeyde karmaklk olumaz. Bir snf kullanlarak yazlar zerinde ilemler yapmak iin MFC snf sisteminde Cstring isimli bir snf tasarlanmtr. Yine son yllarda ANSI C++ ierisine dahil edilen standart bir string snf vardr. Standardizasyon konusundan problemleri olmasna karn yaz ilemlerini yapan bir string snf her trl derleyici sisteminde ve snf ktphanelerinde kullanlmak zere hazr bulundurulmaktadr. Byle bir snfn tasarm iin C++n pek ok konusundan faydalanlmaktadr. Kurs ierisinde eitli konular grlrken bu snf tekrar tekrar grlecektir. String Snfn Tasarm String snfn en az iki private veri eleman olmaldr. Birincisi yaznn balang adresini tutan karakter trnden bir adrestir. Yaz iin alan dinamik olarak tahsis edilerek balang adresi bu gstericiye yerletirilecektir. kinci veri eleman yaznn uzunluunu tutan int trnden bir deiken olabilir. Tabii aslnda yaznn sadece balang adresinin bilinmesi uzunluunun istenildii zaman bulunabilecei anlamna gelmektedir. Ancak yaz uzunluuna duyulan gereksinimin fazlal ve hzn
38

yer kaplamaya gre tercih edilmesi byle bir veri elemannn bulunmasn anlaml hale getirmektedir. Byle bir snftan ilk istenecek ey dinamik yaplan tahsisatlarn ye fonksiyonlar tarafndan gizlice gerekletirilmesidir. Snfn balang fonksiyonu new operatryle tahsisat yapabilir ve biti fonksiyonu bu tahsisat serbest brakabilir. Bir Snfn Baka Bir Snf Trnden Veri Elemanna Sahip Olmas Durumu Bir snf baka bir snf trnden veri elemanna sahipse o snfn ye fonksiyonlar ierisinde eleman olan snf nesnesine eriilebilir. Ancak o snf nesnesinin private ve protected blmlerine eriilemez. Snfn balang fonksiyonu bir ye fonksiyonuymu gibi dardan arlamaz, nesne yaratlrken otomatik olarak arlr. O halde bir snfn baka snf trnden veri elemanna sahip olmas durumunda bu veri elemanna balang fonksiyonu ierisine nasl ilk deer atanacaktr? Bunu salamak iin C++ta eleman olan snfn balang fonksiyonu eleman nesne iin elemana sahip snfn balang fonksiyonunun ana blounun banda gizlice arlr. Eer : syntaxi ile bir belirleme yaplmamsa eleman olan snfn default balang fonksiyonu arlr. Eer : ile veri elemannn ismi yazlp parantez ierisine bir parametre listesi belirtilmise, eleman b parametre listesine uygun balang fonksiyonu ile ilk dee alr. X bir snf a ise baka bir snf trnden X snfnn bir veri eleman ise bu veri eleman iin istenilen bir balang fonksiyonunun arlmas aadaki syntax ile yaplr. X::X(...) : a(..) { ... } Bir parametre deikeninin faaliyet alan tanmlanma noktasndan fonksiyonun sonuna kadar olan blgedir. Yani elemana ilikin : ifadesinde fonksiyon parametreleri dorudan kullanlabilir. /*-----claincla.cpp-----*/ #include <stdio.h> #include <time.h> #include <string.h> class Date { int day, month, year; public: Date(void); Date(int d, int m, int y); void Disp(void) const; }; class Person { char *name;
39

Date bdate; public: Person(const char *nm, int d, int m, int y); void Disp(void) const; ~Person(void); }; Date::Date(int d, int m, int y) { day = d; month = m; year = y; } Date::Date(void) { long t; t = time(NULL); struct tm *p = localtime(&t); day = p -> tm_mday; month = p -> tm_mon + 1; year = p -> tm_year + 1900; } void Date::Disp(void) const { printf("%02d/%02d/%04d\n", day, month, year); } void Person::Person(const char *nm, int d, int m, int y) : bdate(d, m, y) { name = new char[strlen(nm) + 1]; strcpy(name, nm); } void Person::Disp(void) const { printf("%s\n", name); bdate.Disp(); } Person::~Person(void) { delete[] name; } void main(void) { Person X("Ali Sere", 10, 12, 1990);
40

X.Disp(); } /*-------------------------*/ Balang fonksiyonlarnn arlma sralar nce elemana ilikin snfn balang fonksiyonu sonra elemana sahip snfn balang fonksiyonu biimindedir. C++ta her zaman balang ve biti fonksiyonlarnn arlma sras terstir. Bu durumda elemana ilikin snfn biti fonksiyonu elemana sahip biti fonksiyon blounun sonunda otomatik olarak arlr. Yani elemana sahip snfn biti fonksiyonu daha nce arlmaktadr. Bir snfn baka snf trnden birden fazla veri eleman varsa bu veri elemanlar iin balang fonksiyonlar arlma sras snf bildiriminde ilk yazlan nce olacak biimde yaplr. : syntaxi ile belirtilen sra neli deildir. class Y { ......... ........ }; class X { ......... ......... Y a, b; }; X:X(....) : b(...), a(...) { ........ ........ } /*nce ann parametreleriyle belirtilen */ /*Y snfnn balang fonksiyonu arlr. */

Biti fonksiyonlarnn arlma sras balang fonksiyonuna gre ters srada olmak zorundadr. Yani rnekte nce b iin biti fonksiyonu alr. Bir Snfn baka Bir Snf Trnden Gsterici Veri Elamanna Sahip Olmas Durumu Bu duruma dier durumdan daha sklkla rastlanmaktadr. Tabii gsterici veri eleman iin balang fonksiyonu arlmaz. Ancak elemana sahip
41

snfn balang fonksiyonu ierisinde bu gsterici iin dinamik tahsisat yaplmaldr. Elemana sahip biti fonksiyonu ierisinde de delete operatryle balang fonksiyonunda tahsis edilen alan serbest braklmaldr. Bu serbest brakma ile biti fonksiyonu da kendiliinden arlacaktr. /*-----claincl2.cpp-----*/ #include <stdio.h> #include <time.h> #include <string.h> class Date { int day, month, year; public: Date(void); Date(int d, int m, int y); ~Date(void); void Disp(void) const; }; class Person { char *name; Date *bdate; public: Person(const char *nm, int d, int m, int y); void Disp(void) const; ~Person(void); }; Date::Date(int d, int m, int y) { day = d; month = m; year = y; } Date::Date(void) { long t; t = time(NULL); struct tm *p = localtime(&t); day = p -> tm_mday; month = p -> tm_mon + 1; year = p -> tm_year + 1900; } void Date::Disp(void) const { printf("%02d/%02d/%04d\n", day, month, year);
42

} Date::~Date(void) { printf("I am a Date destructor..\n"); } void Person::Person(const char *nm, int d, int m, int y) { name = new char[strlen(nm) + 1]; strcpy(name, nm); bdate = new Date(d, m, y); } void Person::Disp(void) const { printf("%s\n", name); bdate -> Disp(); } Person::~Person(void) { delete[] name; delete bdate; } void main(void) { Person X("Ali Sere", 1, 2, 1990); X.Disp(); } /*-------------------------*/ inline Fonksiyonlar C++ta bir fonksiyon tanmlarken geri dn deerinin nne inline anahtar szc getirilebilir. rnein: inline void fonk(void) { .... } (inline anahtar kullanlmaldr.) szc prototipte deil tanmlama srasnda

Bir inline fonksiyon tpk bir makro gibi ilem grr. Yani inline fonksiyon arldnda fonksiyon arma kodu yerine fonksiyon kodunun kendisi yerletirilir.
43

/*-----inline.cpp-----*/ #include <stdio.h> inline double square(double x) { return x * x; } void main(void) { double n; n = square(3); printf("%lf\n", n); } /*----------------------*/ Inline ile yaplmak istenen makro ile yaplmak istenenle ayndr. Makro n ilemci tarafndan alrken inline fonksiyonlar derleme modl tarafndan almak. inline fonksiyonlar ile makrolar ayn amalar iin kullanlmalarna karn inline fonksiyonlar makrolara gre ok daha kullanl ve salamdr. rnein: Makrolar ++ ve operatrleriyle arlamad halde(pheli kod oluabilir), inline fonksiyonlar gvenli bir biimde arlabilir. nk inline fonksiyonlarda nce parametre ifadesi deerlendirilir, sonra ama ilemi gerekletirilir. Tabii inline fonksiyonlar normal bir fonksiyon gibi yazlp arlrlar. Operatrlerin nceliinden oluacak problemler derleyici tarafndan zaten giderilirler. inline fonksiyon parametrelerini parantez ierisine almaya gerek yoktur. inline fonksiyonlar dier fonksiyonlarda olduu gibi tr dntrmesi ve tr bakmndan derleyicinin denetiminden geerler. Yani inline fonksiyonlarda errorler ortaya kabilir, bylece kod almadan hatalar tespit edilir. Yani daha salamdr. Bu nedenlerden dolay C++ta neredeyse makro hi kulanlmaz. Hep inline fonksiyonlar kullanlr. Snfn normal trlerden veri elemanlar da balang fonksiyonunda : syntaxi ile ilk deer alabilirler. rnein: X::X(void):a(10), b(20) { .... } Edeeri X::X(void) { a = 10; b = 20; }

rnek bir snf: CRect isimli snf MFC snf sistemi ierisinde kullanlan ve drtgensel blgeler zerinde temel ileri yapmay hedefleyen bir snftr. Snfn drtgensel blgeni sol st ve sa alt kegenini belirleyen 4 veri eleman vardr.
44

/*-----crect.cpp-----*/ #include <stdio.h> class CRect { int x1, y1, x2, y2; public: CRect(void); CRect(int c1, int r1, int c2, int r2); int Width(void) const; int Height(void) const; void InflateRect(int width, int height); int IsEmpty(void) const; void Disp(void) const; }; CRect::CRect(void) { x1 = x2 = y1 = y2 = 0; } CRect::CRect(int c1, int r1, int c2, int r2) { x1 = c1; y1 = r1; x2 = c2; y2 = r2; } int CRect::Width(void) const { return x2 - x1; } int CRect::Height(void) const { return y2 - y1; } void CRect::InflateRect(int width, int height) { x1 = x1 + width; x2 = x2 - height; y1 = y1 + width; y2 = y2 - height; } int CRect::IsEmpty(void) const {
45

if(Width() && Height()) return 0; return 1; } void CRect::Disp(void) const { printf("[%d, %d; %d, %d]\n", x1, y1, x2, y2); } void main(void) { CRect a(5, 5, 20, 20); a.Width(); a.Height(); a.Disp(); a.InflateRect(-6, 4); a.Disp(); if(a.IsEmpty()) printf("bo ite\n"); else printf("dolu\n"); } /*---------------------*/ Snfn Veri Elemanlarna Eriim ve this Gstericisi Bir snfn ye fonksiyonu bir snf nesnesiyle arldnda aslnda snf nesnesinin adresi gizlice ye fonksiyona geirilir. ye fonksiyon ierisinde snfn veri elemanlarna erime bu gizlice geirilmi olan gsterici yluyla yaplr. Yani bir ye fonksiyonunun hi parametresi yoksa aslnda gizli bir parametresi vardr. Bu da arlan snf nesnesinin adresini tutan gstericidir. Snfn ye fonksiyonlarnn, snfn veri elemanlarna erimesi aslnda adres yoluyla yaplmaktadr. Tabii kolaylk olmas bakmndan geirilen bu gizli gsterici aka parametre listesinde grnmez. Eriim srasnda ok operatr de kullanlmaz. C++ta ye fonksiyonunu Cdeki karl arlmas void Crect::Disp(void) const void Crect_Disp(const Crect *this) { { printf([%d, %d; %d, %d]\n, printf([%d, %d; %d, %d]\n, x1, y1, x2, y2); this -> x1, this -> y1, } this -> x2, this ->y2); } void main(void) { void main(void) CRect x(10, 10, 20, 20); { x.Disp(); CRect x = {10, 10, 20, 20};
46

} }

Crect_Disp(&x);

ye fonksiyona gizlice geirilen bu adres ye fonksiyon ierisinde aka this anahtar szcyle kullanlabilir. this parametre biiminde programc tarafndan yazlamaz, ancak yazlm gibi kullanlabilir. x bir snfn veri eleman olmak zere ye fonksiyon ierisinde x ile this -> x tamamen ayn anlamdadr. Bir ye fonksiyon baka bir ye fonksiyonu aryorsa aran ye fonksiyona ilikin this gstericisi dorudan arlan fonksiyona geirilir. this gstericisi global fonksiyonlarda kullanlmaz, sadece herhangi bir snfn ye fonksiyonu ierisinde kullanlabilir. this gstericisi hangi snfn ye fonksiyonunda kullanlrsa tr de o snf trnden gsterici olur. this gsterisinin deeri deitirilemez. this gstericisi kendisi const olan const bir gsterici biimindedir. /*-----this.cpp-----*/ #include <stdio.h> class X { int a; public: void fonk(void); }; void X::fonk(void) { printf("%p\n", this); } void main(void) { X n; printf("%p\n", &n); n.fonk(); } /*-------------------*/ Snf i inline Fonksiyonlar Snfn veri elemanlar private ya da protected blme yerletirilmise bu veri elemanlarna eitli public ye fonksiyonlaryla eriilir. Bu tr fonksiyonlara Get ve Set fonksiyonlar denir. Snfn bu tr kk fonksiyonlar tipik inline fonksiyonu olarak yazlmaldr. Bir snfn ye fonksiyonunun tanmlanmas darda deil snfn ierisinde de yaplabilir. rnein: class X { int a, b; public: X(int x, int y)
47

{ a = x; b = y; } }; /*-----inline1.cpp-----*/ #include <stdio.h> #include <conio.h> class X { int a; public: void fonk(void) { printf("%p\n", this); } }; void main(void) { X n; printf("%p\n", &n); n.fonk(); } /*-----------------------*/ Bunun gibi snf bildirimi iinde tanmlanan fonksiyonlar otomatik olarak inline fonksiyon olarak kabul edilir. Snf ierisinde tanmlanm fonksiyonlarn srasnn hibir nemi yoktur. Yani yukardaki fonksiyon aadaki fonksiyonu arabilir. inline bildirimi (darda ya da gizlice snf iinde) bir zorunluluk biiminde deil bir istek biimindedir. Yani derleyici bir inline fonksiyonu inline olarak aamayabilir. Eer aamazsa onu normal bir fonksiyon gibi ele alr. Aamadndan dolay herhangi bir error ya da warning mesaj olumaz(tpk register anahtar szcnde olduu gibi). Genel olarak uzun kod ieren, karmak dng ve if deimleri ieren fonksiyonlar inline olarak alamazlar. Snflarn Tretilmesi Daha nce yazlm olan bir snfa ekleme yaplmas istendiinde bavurulacak en iyi yntem tretme ilemidir. Bir snfa ek yapmak snfa yeni veri ve ye fonksiyonu eklemek anlamndadr. Bir snfa ek yapmak iin tretme dnda birka yntem akla gelebilir: 1. Snfa dorudan Bu durumda nceki snfn bir kopyas kartlr ve zerinde eklemeler yaplrsa, gereksiz bir biimde ekleme yapmak ye fonksiyon tekrar yaplr.
48

T?retme bi?imi

2. nceki snf bir class A { veri eleman olarak //... kullanan yeni bir }; class B { snf tanmlamak A a; //... }; Bu durumda veri eleman public blgeye yerletirilirse geniletilecek snfn ye fonksiyonlar bu nesne sayesinde arlr. Ancak bu yntem de tretme yntemine gre eitli kstlamalar olan bir yntemdir. Bir snfn ilevleri tretme yoluyla geniletilecekse tretmenin yaplavca snfa taban snf (base class), tretilmi olan snfa da tremi snf (derived class) denir. ekilsel olarak tremi snftan taban snfa bir ok olarak belirtilir. Tretme ileminin genel biimi:

class <tremi snf ismi>:[private/protected/public]<taban snf ismi> { } rnek: class A { int a; //... }; class B:public A { int b; //... }; ki nokta stste ayracndan sonra istee bal olarak tretme biimi yazlabilir. Yazlmazsa private yazlm gibi ilem grr. Tremi snf trnden bir nesne tanmlandnda bu nesne hem taban snf veri elemanlarn hem de tremi snf veri elemanlarn ierir.

/*-----turetme.cpp-----*/ #include <stdio.h> class A {


49

public: int a; }; class B:public A { public: int b; }; void main(void) { B x; printf("%d\n", sizeof(x)); } /*------------------------*/ Tremi Snf Nesnesinin Bellekteki Organizasyonu Tremi snf nesnesinin taban snf veri elemanlar ve tremi snfn kendi veri elemanlar blok olarak ardl bir biimde yerletirilir. Ancak taban snf ve tremi snf veri elemanlarnn hangisinin daha dk adres blgesine yerletirilecei ANSI standartlarnda belirlenmemitir, dolaysyla derleyiciyi yazanlara braklmtr. A B B A

Tabii derleyici organizasyonu hep ayn yapar. Yaygn kullanlan derleyicilerde taban snf veri elemanlar dk anlaml adresi yerletirilmektedir(Kursta btn rneklerde nce taban snf veri elemanlar dk anlaml adrese yerletirilecektir). Tremi Snflarda Eriim Kural Tremi snflardaki eriim kural tretme biimine baldr. Public Tretmesi Public tretmesinde taban snfn public blm tremi snfn public blmym gibi, taban snfn protected blm de tremi snfn protected blmym gibi ilem grr. Taban snfn private blm eriime kapaldr. Taban snfn private blmne tremi snf tarafndan eriilemez. Taban private protected public Tremi protected public

50

Public Tretmesinden kan Sonular 1. Tremi snf nesnesi yoluyla dardan nokta ya da ok operatr kullanlarak taban snfn public blmne eriilebilir. Ancak taban snfn protected ve private blmne eriilemez. 2. Tremi snf ye fonkiyonlar ierisinde taban snfn public ve protected blmlerine dorudan eriilebilir.ancak taban snfn private blmne eriilemez. Protected Tretmesi Bu tretme biiminde taban snfn public ve protected blmleri tremi snfn protected blmym gibi ilem grr. Taban snfn private blm eriime kapaldr. Tremi snf tarafndan eriilemez. Taban private protected public Tremi protected Protected Tretmesinden kan Sonular 1. Tremi snf nesnesiyle dardan nokta ya da ok operatryle taban snfn hibir blmne eriilemez. 2. Tremi snf ye fonksiyonlar ierisinde taban snfn public ve protected blmlerine dorudan eriilebilir. Ancak private blmlerine eriilemez. Private Tretmesi Bu durumda taban snfn public ve protected blmleri tremi snfn private blmym gibi ilem grr. Taban snfn private blm eriime kapaldr. Tremi snf tarafndan eriilemez. Taban private protected public Tremi private Private Tretmesinden kan Sonular 1. Tremi snf nesnesi yoluyla dardan nokta ya da ok operatryle taban snfn hibir blmne eriilemez. 2. Tremi snf ye fonksiyonlar ierisinde taban snfn public ve protected blmlerine dorudan eriilebilir. Ancak private blmlerine eriilemez. Tretme leminden kan Ortak Sonular 1. Tremi snf nesnesi yoluyla dardan nokta veya ok operatr
51

kullanlarak ancak taban snfn public blmne ancak public tretmesiyle eriilebilir. Hibir zaman dardan taban snfn protected ya da private blmne eriilemez. 2. Tremi snf ye fonksiyonlar ierisinde tretme biimi ne olursa olsun taban snfn public ve protected blmlerine eriilebilir. 3. Taban snfn private blm tam olarak korunmutur. Tremi snf tarafndan dorudan hibir ekilde eriilemez. En ok kullanlan tretme biimi public tretmesidir. Protected Blmnn Anlam Protected blm dardan dorudan eriilemeyen, ancak tremi snf ye fonksiyonlar tarafndan eriilebilen bir blmdr. Protected blmnn tretme dnda zel bir anlam yoktur. nk bu blm tremi snfn eitli ilemlerini kolaylatrmak iin gereksinimlerini tutmakta kullanlr. Private Blme Fonksiyonlar Yerletirilmesi Bir snfn public blmnde bulunan X() isimli fonksiyon ilemini gerekletirmek iin ilemin belirli blmlerini yapan, yani ara ilemleri yapan eitli fonksiyonlar kullanabilir. Bu ara ilemleri yapan fonksiyonlarn dardan arlmasnn hibir anlam yoktur. Algdan uzak tutmak amacyla private blme yerletirilebilirler. Snf kullanacak kii iin private blgenin incelenmesi gereksizdir. Somut, Soyut ve Arabirim Snflar Kendisinden baka bir snf tretilmeyecek biimde tasarlanan snflara somut snflar (concreate cleass) denir. Somut snflar belirli bir konuda yararl ilemleri yaparlar. Genellikle ilevlerinin geniletilmesi biiminde bir istek sz konusu olmaz. Soyut snflar (abstract class) kendi bana bir anlam olmayan kendisinden tretme yaplarak kullanlmas zorunlu olan snflardr. C++ta soyut snflar derleyici tarafndan belirli bir syntax iimiyle dorudan desteklenirler. Arabirim snflar (interface class) en ok rastlanan snflardr. Kendi balarna yararl ilemeleri yapabilen, ancak tretme ilemine de izin verebilecek biimde tasarlanm snflardr. Arabirim snflar tasarlayan kii bunlar tretme durumunu gz nne alarak tasarlamaldr. Tretme lemine Birka rnek Seri port ilemlerini yapan serial isimli bir snf olsun. Bu snfn ye fonksiyonlar portu set etme, okuma ve yazma gibi temel ilemleri yapsn. Modem seri porta balanarak kullanlan, ve iletiimi salayan bir
52

CWndpublic public CDialog ublic MyDialog CWndp CDialog

aratr. Modemi programlamak iin seri porta bilgi gndermek gerekir. Modem ilemlerini yapmak iin serial snfndan tretme uygulanabilir. Benzer biimde laplink kablosu kullanarak seri portlar aras bilgi transferi iin laplink isimli ayr bir snf tretilebilir. MFC snf sisteminde CWnd snf genel olarak her trl pencereyle ilgili ilem yapmak amacyla kullanlr. Dialog pencereleri zel pencerelerdir. Yani bir pencerenin tm zelliini gsterir, ancak ek zelliklere de sahiptir. CDialog snf CWnd snfndan tretilmitir.

Ancak her dialog penceresi kendine zg farkllklara sahiptir. MFCde ne zaman bir dialog penceresi alacak olsa CDialog snfndan bir snf tretilmeli ve dialog penceresi o snfla ilikilendirilmelidir.

Bu durumda MyDialog snfna ilikin bir nesne tanmlanrsa bu nesne yoluyla CWnd snfna ilikin ye fonksiyonlar arldnda; pencereye ilikin temel ilemler, CDialog snfnn ye fonksiyonlar arldnda dialog pencerelerine ilikin genel ilemler ve nihayet MyDialog snfna ilikin ye fonksiyonlar arldnda kendi dialog penceremizle ilgili zel ilemler yaplacaktr. Tremi Snflarda Faaliyet Alan Snf faaliyet alan bir snfn ve ondan tremi olan snflarn ye fonksiyonlar arasnda tannabilme araldr. Bir veri eleman ya da ye fonksiyonu ayn isimle taban ve tremi snflarda tanml olabilir. Bu durumda: 1. Tremi snf ye fonksiyonu ierisinde ilgili isim dorudan kullanlrsa dar faaliyet alanna sahip olan yani tremi snfta tanlanm olan anlalr. Eer istenirse znrlk operatryle snf ismi belirtilerek (X::a = 10) taban snftaki isme eriilebilir. 2. Tremi snf nesnesi yoluyla dardan nokta ya da ok operatryle
53

A B

1FC2

ayn isimli deikene ya da fonksiyona eriildiinde yine dar faaliyet alanna sahip olan tremi snftaki isim anlalr. Ancak nokta ya da ok operatrnden sonra yine znrlk operatr kullanlabilir (p->X::a). 1FC0 3. Taban ve tremi snf ierisinde ayn isimli fakat farkl parametre yaplarna sahip fonksiyonlar olsun. Eer tremi snfn baka birt ye fonksiyonunda ayn isimli fonksiyon arlmsa bu fonksiyon yalnzca dar faaliyet alannda aranr. Yani parametre yaplar farkl bile olsa dar faaliyet alanndaki dierini gizlemektedir. Ayn durum dardan tremi snf nesnesi yoluyla nokta ya da ok operatryle de sz konusu olur. Yani dar faaliyet alanndaki isim geni faaliyet alann gizleyerek bu ismin orada aranmamasn salar(Global fonksiyon arrken :: operatr fonksiyon isminin nne getirilir). Bir snfn ye fonksiyonu ierisinde bir fonksiyon arm olsun. Derleyici bu ismi srasyla uralarda arar(name lookup): a. ye fonksiyona ilikin snf ierisinde, b. ye fonksiyonun taban snflar ierisinde, c. Global faaliyet ierisinde aranr. Bir ye fonksiyon ierisinde fonksiyon ismi, snf ismi ve znrlk operatryle arlmsa isim srasyla uralarda aranr: a. sim znrlk operatryle belirtilen snfta aranr. b. Bulunamazsa znrlk operatryle belirtilen snfn taban snfnlarnda aranr. Ancak global faaliyet alannda aranmaz. Eer unary znrlk operatr ile arlmsa (::fonk(); ) isim yalnzca global faaliyet alannda aranr. Bir snfn ye fonksiyonu ierisinde snfn ve taban snflarn global fonksiyonla ayn isimli fonksiyonlar olmasa bile arma ilemi okunabilirlik bakmndan yine unary znrlk operatr kullanlarak yaplmaldr. Fonksiyonlar iin belirtilen bu arama durumlarnn hepsi normal deikenler iin de geerlidir. Tremi Snfn Taban Snf armas lemleri Normal olarak tremi snf taban snfa eriebilir. Yani tremi snf nesnesiyle ya da tremi snf ye fonksiyonlar ierisinde taban snf nesnesi ya da fonksiyonlar kullanlabilir. ancak tersi durum mmkn deildir. Yani taban snf tremi snfa eriemez. Taban snf derlenirken derleyici bundan bir snf tretileceini bilmek zorunda deildir. Bu durumda tremi snf nesnesi ile taban snf ye fonksiyonu arldnda derleyici bu fonksiyona this gstericisi olarak tremi snf nesnesinin taban ksmnn adrsini geirir. Uygulamada taban snf veri elemanlar daha dk adrese yerletirildiinden geirilen adres nesnenin btnsel balang adresiyle ayn olur. B x; x.fonka(); Burada A taban snfnn fonka ye fonksiyonuna this gstericisiyle 1FC0 adresi geirilmektedir. Tremi snf nesnesiyle tremi snfn ye
54

fonksiyonu arldnda yine taban snf veri elemanlarnn bulunduu toplam veri adresi geirilir. nk tremi snf ye fonksiyonu ierisinde taban snf ye fonksiyonu arldnda derleyici taban snf veri blounun adresini tespit edebilmek zorundadr. Bir Dizi Tretme Yaplmas Durumu Tretme ilemi birden fazla yaplabilir Bu durumda yukardaki snflar ayn kurallarla aadan eriilebilir. Bir snfn bir dizi tretme yapldnda bir steki taban snfna dorudan tan snf (direct base class) sonraki taban snflarna ise dolayl taban snf (indirect base class) denir. Bir snf birden fazla snofa taban snf olabilir. Bu durum atmaya yol amayacak biimde ak ve anlalr bir tretme durumudur.

Ancak bir snffn birden fazla taban snfa sahip olmas ayr bir blmde incelenecek kadar karmak bir konudur. Bu duruma oklu tretme denir. oklu tretme dier bilgisayar dillerinde desteklenmemektedir.

Taban Snf Trnden Gstericilere Tremi Snf Nesnelerinin Adreslerinin Atanmas C++'ta bir gstericiye farkl trden bir gstericinin atanmas uyar deil error gerektirir. Ancak istisna olarak taban snf trnden bir gstericiye tremi snf trnden bir nesnenin adresi atanabilir. Ancak bunun tersi olan durum, yani tremi snf trnden bir gstericiye taban snf trnden bir nesnenin adresinin atanmas durumu yararl ve geerli bir ilem deildir. class A {
55

.. .. }; class B:public A { .. .. }; void main(void) { A *p; /*Taban snf trnden bir gsterici*/ B x; /*Tremi snf trnden nesne*/ A y; /*Taban snf trnden bir nesne*/ B *t; /*Tremi snf trnden bir gsterici*/ p = &x; t = &y; } Tremi snf nesnesi taban snf veri elemanlarn ierdiine gre tremi snf nesnesinin adresi taban snf gstericisine geirildiinde problemli ya da gvensiz bir durum olumaz. Derleyici bu durumda tremi snf nesnesinin taban snf veri elemalarnn adresini gstericiye atar. Taban snf gstericisiyle ancak taban snf ye fonksiyonlar arlabileceine gre bu gstericiyle tahsis edilmi bir alana eriilir, yani uygunsuz bir durum olumaz. Mademki taban snf ve tremi snf veri elemanlarnn yerleimi kesin bir standartla belirlenmemitir, byle bir atamada derleyici tremi snf nesnesinin taban snf elemanlarnn balang adresini tespit edip o adresi atamaldr. Tabii genellikle taban snf veri elemanlar dk anlaml adrese yerletirildiinden geirilen adres de nesnenin btnnn balang adresi olur. /*-----tabangos.cpp-----*/ #include <stdio.h> class A { int a; public: A(int x = 0) { a = x; } void DispA(void); void SetA(int x) { a = x; } }; /*Geerli*/ /*Geersiz*/

56

class B : public A { int b; public: B(int x = 0, int y = 0): A(y) { b = x; } void DispB(void); void SetB(int x) { b = x; } }; void A::DispA(void) { printf("%d\n", a); } void B::DispB(void) { printf("%d\n", b); } void main(void) { A *p; B x(10, 20); p = &x; p -> DispA(); p -> SetA(50); p -> DispA(); } /*------------------------*/ rnek:C B'den, B A'dan tremi snflardr: { B *p; C n; p = &n; } Tremi Snf Nesnesinin Adresinin Taban Snf Gstericisine Atanmas leminin Program erisinde Karlalabilen eitli Durumlar Tremi snf nesnesinin adresi ak ya da gizli eitli kodlarla taban snf
57

/*Geerlidir, p'ye A'nn balang adresi, geirilir*/

gstericisine geirilebilmektedir. 1. Ak bir biimde yaplan atamalarla: Yani taban snf trnden bir gsterici tanmlanr, tremi snf trnden bir nesnenin adresi atanr. { A *p; /*Taban snf trnden bir gsterici*/ B x; /*Tremi snf trnden nesne*/ p = &x; /*Geerli*/

} 2. Fonksiyon arma yoluyla ve gsterici kullanlarak: Bu durumda fonksiyonun parametre deikeni taban snf trnden bir gstericidir. Fonksiyon tremi snf nesnesinin adresiyle arlr. Bu biimde atama ilemi en sk rastlanan atama ilemidir. void fonk(A *p) { p -> DispA(); } void main(void) { B n(10, 20); fonk(&n); } 3. Aka ve referans kullanlarak yaplan atamalar: Taban snfa ilikin bir referans tremi bir snfa ilikin bir nesneyle ilk deer verilerek tanmlanabilir. Derleyici bu durumda tremi snf nesnesinin taban snf veri eleman blounun adresini taban snf referansna atar. { B n(10, 20); A &r = n; r.Disp(); } 4. Fonksiyon arma yoluyla ve referans kullanlarak: Bu durumda fonksiyonun parametre deikeni taban snf trnden bir referanstr. Fonksiyon da tremi snf nesnesinin kendisiyle arlr. /*Geerli*/ /*Geerli*/

58

void fonk(A &p) { p.DispA(); } void main(void) { B n(10, 20); fonk(n); } Taban Snf Gstericisine Tremi Snf Nesnesin Adresinin Atanmasnn Faydalar Bir dizi tretme sz konusu olduunda tretme ierisindeki her snfn ortak veri elemanlar sz konusu olabilir. rnein yle bir tretme sz konusu olsun:

(D B'den, E C'den, B ve C de A'dan tremi snflar olsun). rnein burada tretilmi snflarn hepsi A snfn iermektedir. Yani bu snflarn hepsi A snf gibi de davranabilmektedir. Burada A veri elemanlar zerine genel ilemler yapan bir fonksiyon sz konusu olsun: void fonk(A *p) { } Tremi snflarn herhangi birine ilikin nesnenin adresiyle bu fonksiyon arlabilir. Yani bylece trden bamsz olarak ilem yapabilen fonksiyonlar yazlabilmektedir. Taban Snf Gstericisine Tremi Snf Nesnesinin Atanmasna likin Birka rnek 1. Bir iletmede alan kiiler gruplanarak bir snf ile temsil edilmi olsun.

59

alan hangi gruptan olursa olsun onun genel zellikleri zerinde ilem yapan ProcessPersonalInfo() fonksiyonu olsun: ProcessPersonalInfo(Employee *p); Bu fonksiyona hangi snf trnden nesne verirsek verelim o snfn genel alan zellikleri zerinde ilemler yaplabilir. { Manager x(....); Salesperson y(...); ProcessPersonalInfo(&x); ProcessPersonalInfo(&y); } 2. MFC snf sisteminde her trl pencere zerinde ilem yapabilen bir CWnd snf vardr. Editbox, puchbutton ve dialog pencereleri de bir eit penceredir. Bu zel pencereler zerinde ilem yapabilen CWnd zerinden tretilmi ayr snflar vardr.

Pencerenin tr ne olursa olsun, onun genel pencere zellii zerinde ilemler yapan global bir ProcessWnd() fonksiyonu yazldn dnelim. Bu fonksiyon her trl pencere zerinde ilem yapabilecektir. void ProcessWnd(CWnd *p) { } { CButton button; CDialog dialog; ProcessWnd(&button); ProcessWnd(&dialog);
60

} Snfn Static Veri Elemanlar Veri elemanlar snf ierisinde static anahtar szcyle bildirilebilir. Byle bildirilmi static veri elemanlar snfn kendi veri elemanlarna dahil edilmez. /*-----static.cpp-----*/ #include <stdio.h> class X { static int x; int a; public: void fonk(void) { } }; void main(void) { X n; printf("%d\n", sizeof(X)); /*2*/ } /*--------------------*/ Snfn static veri elemanlar aslnda bir eit global deikendir, yalnzca snf ile ilikilendirilmitir. Yani adeta yalnzca snfn eriebildii global bir deikendir. Bunlar C'ce normal global deikenler gibidirler, yani static mrldrler. Snfn static veri elemanlarndan bir tane bulunur. Bu elemana bir snf elemanym gibi eriilir. /*-----static1.cpp-----*/ #include <stdio.h> class X { public: static int x; int a; void fonk(void) { } }; int X::x; void main(void) { X n; X z; n.x = 50;
61

printf("%d\n", z.x);/*50*/ } /*---------------------*/ Snfn static veri eleman ayrca darda global bir biimde tanmlanmak zorundadr. Bu tanmlama veri eleman snfn hani blgesinde olursa olsun tanmlanmak zorundadr. Snfn static veri eleman normal bir veri elemanym gibi eriim kuralna uyar. /*-----static2.cpp-----*/ #include <stdio.h> class X { private: static int x; int a; public: X(int r) { a = r; ++x; } int GetCount(void) { return x; } }; int X::x = 0; void main(void) { X a(10); X b(20); printf("%d\n", b.GetCount()); } /*---------------------*/ Snfn static veri elemanna hangi snf nesnesiyle eriildiinin hibir nemi yoktur.Bu nedenle snfn static veri elemanna dorudan snf nesnesi olmadan snf ismi ve znrlk operatryle de eriilebilir. Snf_ismi::static_veri_eleman_ismi Tabii bu eriimin geerli olabilmesi iin veri elemannn public blgede olmas gerekir. Genellikle snfn static veri eleman public blgeye yerletirilir ve dardan bu biimde eriilir. Static Veri Elemanlar Neden Kullanlr
62

Bazen bir snf global deikene gereksinim duyabilir. Ama o global deiken yalnzca o snf iin anlaml olabilir. Eer bu deiken snfn static veri eleman yaplrsa yalnzca bir snfla ilikilendirilmi olur. Alglama iyiletirilir. Snfn static veri eleman bir dizi biiminde olabilir. rnein tarihlerin yazdrlmas iin kullanlacak, aylarn isimlerini tutacak gsterici dizisi global yerine snfn static veri eleman biiminde alnabilir. Bylece hem her snf nesnesi iierisinde ayrca yer kaplamaz, hem de snfa ilikilendirilmi olur. /*-----static4.cpp-----*/ class Date { private: static char *mon[12]; int day, month, year; public: /* .... .... .... */ void Disp(void); }; char * Date::mon[12] = {"Ocak", "ubat", "Mart", "Nisan", "Mays", "Haziran", "Temmuz", "Austos", "Eyll", "Ekim", "Kasm", "Aralk"}; /*---------------------*/ Snfn Static ye Fonksiyonlar Snfn static ye fonksiyonlar normal bir ye fonksiyonu gibidir. Ancak bu fonksiyonlara this gstericisi geirilmez, yani bu fonksiyonlar ierisinden snfn veri elemanlarna eriilemez. Yani adeta snfla ilikilendirilmi global bir fonksiyon gibidirler. Yani snfn veri elemanlarn kullanmayan ancak mantksal olarak snfa ilikili olan global fonksiyonlar snfn static fonksiyonu yaplabilir. Snfn static ye fonksiyonuna this gstericisi geirilmediine gre bu fonksiyonun da zel olarak bir nesne ile arlmasnn anlam kalmaz. Snfn static ye fonksiyonu snf ismi belirtilerek znrlk operatryle dorudan arlabilir. Tabii eriim kural bakmndan public blgede bildirilmi olmas gerekir. Snfn static ye fonksiyonu ierisinde snfn static olmayan bir ye fonksiyonu arlamaz, static olmayan bir veri eleman kullanlamaz. Ama snfn static veri elemanlar kullanlabilir ve static ye fonksiyonlar arlabilir. Farkl snflarn ayn isimli static ye fonksiyonlar ya da veri elemanlar bulunabilir. /*-----static5.cpp-----*/ #include <stdio.h> class X {
63

private: int a; static int b; public: X(int n) { a = n; ++b; } void Disp(void); static void Fonk(void); }; int X::b = 0; void X::Disp(void) { printf("%d\n", a); } void X::Fonk(void) { printf("%d\n" ,b); } void main(void) { X n1(50); X n2(60); X::Fonk(); } /*---------------------*/ Arkada Fonksiyonlar Global bir fonksiyonu bir sfn arkada fonksiyonu yapabilmek iin prototipinin nne friend szc getirilmelidir. Arkada fonksiyonlar darda normal global fonsiyonlardr. Ancak eriim bakmndan ayrcalkl fonksiyonlardr. Arkada fonksiyonlar eriim bakmndan ayrcalkldr. Bir arkada fonksiyon ierisinde arkada olunan snfa ilikin bir nesne tanmlanrsa o nesne yoluyla snfn her yerine eriilir. Bir fonksiyon birden fazla snfn arkada fonksiyonu olabilir. Arkada fonksiyon bildirimi snfn herhangibir blmnde yaplabilir. Hangi blmde yapldnn hibir etkisi yoktur. Arkada fonksiyonlar snfn private ve protected blmlerinin korunmasn zayflatr. Yani snfn veri yaps deitirildiinde bu fonksiyonlarn da yeniden yazlmas gerekir. /*-----static6.cpp-----*/ #include <stdio.h>
64

class X { int a; public: X(int n) { a = n; } void Disp(void) const; friend void fonk(void); }; void X::Disp(void) const { printf("%d\n", a); } void fonk(void) { X n(20); printf("%d\n", n.a); } void main(void) { fonk(); } /*-------------------------*/ Baka bir snfn bi ye fonksiyonu da bir snfn arkada fonksiyonu yaplabilir. friend Y::sample(void); Fonksiyonun parametre parantezi de fonksiyona dahildir. Yani genellikle arkada fonksiyonu parametresi arkada olunan snfna ilikin bir gsterici ya da referans olur, fonksiyon ierisinde bu snfn her blmne eriilir. class X { private: int a; public: friend void fonk(const X *p); }; void fonk(const X *p) { printf("%d\n", p->a); }
65

void main(void) { X n(20); fonk(&n); } Arkada Fonksiyonlar Ne Zaman Kullanlr? Baz tasarmlarda az sayda fonksiyon snfn private blm zerinde youn ilemler yapyor olabilir. Bu az sayda fonksiyon iin arabirim public ye fonksiyonlar yazmak etkin grnmeyebilir. te bu durumlarda arkada fonksiyonlarla eriim kural bozulabilir. Tabii arkada fonksiyonlarn ar lde kullanlmas korunmay azaltarak private blgeyi anlamasz hale getirebilir. Friend fonksiyon bildirimi global fonksiyonlar iin prototip yerine de geer. Arkada Snflar Bir snf btn olarak arkada snf olarak bildirilebilir. class X { int a; public: X(int n) { a = n]; friend class Y; }; Bu durumda snfn btn elemanlar arkada kabul edilir.Yani o snfn tm ye fonksiyonlar ierisinde arkada olunan snfa ilikin nesne tanmlanrsa o nesne yoluyla snfn her tarafna eriilebilir. class Node { int data; Node *next; friend class LList; }; class LList { Node *head; public: void Add(int d); void Delete(void); }; Deikenler ve Snf Faaliyet Alan C'de ve C++'ta aslnda yalnzca nesnelerin deil her trden deikenlerin faaliyet alan vardr. rnein bir blok ierisinde bir typedef ismi bildirilirse o typdef ismi o bloun dndan kullanlamaz. Bir snf ierisinde typedef,
66

enum, struct, baka bir snf ya da union bildirimi yaplabilir. Bu bildirimere ilikin isimlere ancak o snflarn ye fonksiyonlar ierisinden dorudan eriilebilir(yani snf ismi belirtmeden). Ancak bu isimler snfn public blmndeyse snf ismi ve znrlk operatryle eriim salanabilir. rnein: class X { public: typedef int *PINT; ... ... ... }; void main(void) { PINT n; X::PINT n; }

/*Error*/ /*Doru kullanm*/

Bir snfn ierisinde baka bir snf ya da yap bildirimi de yaplabilir. Bu durumda ierde bildirilmi olan snf yalnzca darda bildirilmi snf ierisinden dorudan kulanlabilir. rnein: class X { public: class Y { ... ... }; ... ... }; void main(void) { Y n; X::Y n; }

/*Error*/ /*Doru kullanm*/

Bir snf bir snf ieriyorsa aralarnda hibir veri eleman ierme gibi bir durum yoktur(yani C'deki i ie yaplarda olduu gibi deildir). Aslnda bu iki snf tamamen birbirlerinden farkl bamsz olarak darda bildirilebilecek iki snftr. eride bildirilmi snf yalnzca dardaki snf ierisinde isim bakmndan dorudan kullanlabilir. Sanal Fonksiyonlar Taban snf ve tremi snflarda ayn isimli fonksiyonlar varsa, arma
67

znrlk operatryle yaplmamsa, eer taban snf nesnesi ya da gstericisine ilikin bir arma sz konusuysa taban snfn fonksiyonu doal olarak arlacaktr. Snfn bir ye fonksiyonu sanal fonksiyon yaplabilir. Bir ye fonksiyonu sanal fonksiyonu yapabilmek iin fonksiyon prototipinin nne virtual anahtar szc getirilir. virtual anahtar szc sadece prototip bildirirken kullanlr, fonksiyon tanmlanrken kullanlmaz. Bir ye fonksiyon sanal yaplrsa o snfn tremi snflarnda bulunan ayn isimli , ayn prototipe sahip tm fonksiyonlar da sanal olur. Yani virtual anahtar szc yazlmasa da yazlm gibi ilem grr. Ayn prototipe sahip olmas demek geri dn deerlerinin parametre yaplarnn ve fonksiyon isimlerinin ayn olmas demektir(const'luk dahil). Tremi snf nesnesinin adresi taban snf gstericisine atanr ve bu gsterici yoluyla sanal fonksiyon arlrsa adresi alnan nesne hangi snfa aitse o snfn sanal fonksiyonu arlr. Taban snfn tremi snfa erimesi ancak bu koullarda mmkn olmaktadr. Bir dizi tretme yapldnda tremi snflardan birine ilikin nesnenin adresi taban snflardan birine ilikin gstericiye geirilebilir ve bu gsterici yoluyla sanal fonksiyon arlabilir. Snf ismi belirtilerek sanal fonksiyon arlrsa sanallk zellii kalmaz. /*-----virtual.cpp-----*/ Sanal Fonksiyonlarn Program erisindeki arlma Biimleri Program ierisinde sanal fonksiyon u biimlerde arlabilir: 1. Tremi snf nesnesinin adresinin ak bir biimde taban snf nesnesine atanmas yoluyla void main(void) { B z(10, 20); A *p; p = &z; p -> Disp(); } 2. Fonksiyonun parametre deikeni taban snf trnden bir gstericidir. Fonksiyon da tremi snf nesnesinin adresiyle arlr. Bu gsterici yoluyla sanal fonksiyon arlabilir. void fonk(A *p) { p -> Disp(); }

68

void main(void) { B n(10, 20); fonk(&n); } 3. Taban snf trnden bir referans tremi snf trnden nesneyle ilk deer verilerek tanmlanr. Bu referans yoluyla sanal fonksiyon arlabilir. Bu durumda tremi snfa ilikin sanal fonksiyon arlacaktr. void main(void) { B n(10, 20); A &r = n; r.Disp(); } 4. Fonksiyonun parametre deikeni taban snf trnden bir referans olur. Fonksiyon da tremi snfn nesnesinin kendisiyle arlr. Fonksiyon ierisinde bu referans yoluyla tremi snfa ilikin sanal fonksiyon arlr. void fonk(A &r) { r.Disp(); } void main(void) { B n(10, 20); fonk(n); } 5. Tremi snf trnden bir nesne ile taban snfa ilikin bir ye fonksiyonu arlrsa, bu ye fonksiyon ierisinde de sanal fonksiyon arlrsa ye fonksiyon hangi snfa ilikin nesne ile arlmsa o snfa ilikin sanal fonksiyon arlr. void A::fonk(void) { Disp(); } void main(void) { B n(10, 20); n.fonk();
69

} Tabii ye fonksiyon ierisinde arma ilemi znrlk operatr ve snf ismi beliritilerek yaplrsa sanallk zellii kalmaz. Taban snf sanal fonksiyona sahip olduu halde tremi snf sanal fonksiyona sahip olmayabilir. Yani tremi snf iin sanal fonksiyonun tanmlanmas zorunlu deildir. Sanal fonksiyona sahip olmayan tremi snfa ilikin bir snf nesnesinin adresi taban snf gstericisine atanr ve bu gsterici yoluyla sanal fonksiyon arlrsa tremi snfn sanal fonksiyona sahip ilk taban snfnn sanal fonksiyonu arlr. Sanal fonksiyon arlabilmesi iin tretme biiminin public olmas gerekir. Bir sanal fonksiyon arldnda gerekte arlacak olan tremi snfn sanal fonksiyonu snfn herhangi bir blmnde olabilir. Ancak arlma ifadesindeki nesneye ilikin snfn sanal fonksiyonu public blmde olmak zorundadr. rnein : A *p; C n; p = &n; p -> fonk(); Burada fonk sanal bir fonksiyon olsun, gerekte arlacak olan fonk C snfnn fonksiyonudur. C snfnn fonk sanal fonksiyonu snfn herhangi bir blmnde bildirilmi olabilir, ancak armann mmkn olabilmesi iin A snfnn fonk sanal fonksiyonunun public blmde bildirilmi olmas gerekir. Sanal Fonksiyon armann Nedenleri Sanal fonksiyon armann iki faydal nedeni vardr: 1. Bir snfn ilevini deitirmek, 2. Trden bamsz ilemler yaplmasna olanak salamak. rnein A gibi bir snf varsa, bu snf belirli ilemleri yapyorsa, bu snfa hi dokunmadan snfn yapt ilemler zerinde deiiklik yaplmas salanabilir. Sanal Fonksiyon Kullanlmasna likin rnekler 1. ngilizce yazlar zerinde ilem yapan bir CString snf olsun. Bu snfn yazlar karlatran, byk harf ya da kk harfe dntren ye fonksiyonlar olsun. Yazlarn karlatrlmas ve harf dnmnn yaplmas dile bal bir durumdur. CString snfnn Cmp isimli karlatrma fonksiyonu ilemini yaparken iki karakteri karlatran sanal Cmphr fonksionunu aryor olsun. CString snfndan bir snf tretilir, CmpChr sanal fonksiyonu bu snf iin yeniden yazlrsa, artk Cmp fonksiyonu tremi fonksiyonunun CmpChr fonksiyonunu aracak ve ilemler baka
70

bir dile gre dzgn yaplabilecektir. 2. Bir dizinin Array isimli bir snfla temsil edildiini dnelim. Bu snfn sraya dizme ilemini yapan sanal bir sort fonksiyonu olsun. Baz ye fonksiyonlar da bu fonksiyonu ararak sort ilemini gerekletirsin. Sort algoritmas ok eitli olabilir. Bu snftan bir snf tretilerek bu sanal fonksiyon baka bir sort algoritmasn kullancak biimde yeniden yazlabilir. Bu durumda bizim istediimiz sort algoritmasyla ilemler yrtlecektir. 3. MFC snf sisteminde her trl pencere ilemleri CWnd snf tarafndan yaplmaktadr. Dialog penceresi de zel bir tr penceredir. Dialog penceresi ilemleri CWnd snfndan tretilen CDialog snf ile yaplmaktadr. Her dialog penceresi dierinden farkl zelliklere sahip olabilir. O ilemler de CDailog snfndan tretilen snfla temsil edilir.

Dialog penceresini grnr hale getirmek iin CDialog snfnn DoModal() fonksiyonu arlr. CDialog snfnn OnOk ve OnCancel sanal fonksiyonlar vardr. CWnd snfndan tretilen bir snfa ilikin bir nesne tanmlandnda CWnd snfnn balang fonksiyonu ile yaratlan nesnenin adresi MFC sistemi tarafndan global bir biimde saklanr. Ne zaman bir dialog penceresinde OK ya da CANCEL tularna baslrsa MFC saklam olduu adresle OnOk ya da OnCancel fonksiyonlarn arr. Eer biz bu fonksiyonlar yeniden yazarsak bizimki arlacaktr. Tabii orijinal OnOk ve OnCancel fonksiyonlar kritik baz ilemleri de yapmaktadr. Bu durumda bu fonksiyonlarn dordan armalar da gerekebilir. void MyDialog::onOK(void) { .... .... CDialog::OnOK(); } Sanal Fonksiyonlarn Mekanizmasnn Kurulmas Bir tremi snf nesnesinin adresi taban snf gstericileriyel dolatrlm olabilir ve en sonunda sanal fonksiyon arlsa bile nesnenin orijinaline ilikin sanal fonksiyon arlacaktr. peki derleyici bu olay derleme zaman srasnda belirleyebilir mi? Bu olayn derleme srasnda tespit edilmesi mmkn deildir. Gerekte hangi sanal fonksiyonun arlacan
71

belirlemek ancak runtime srasnda kurulacak bir mekanizmayla mmkn olabilir. Bu mekanizmann runtime srasnda kurulmasna ingilizce late binding denilmektedir. class A { public: virtual void fonk1(void); virtual void fonk2(void); }; class B : public A { public: virtual void fonk1(void); virtual void fonk2(void); }; class C : public B { virtual void fonk1(void); virtual void fonk2(void); }; void sample(B *p) { sample2(p); } void sample2(A *p) { p -> fonk1(); } void main(void) { C x; B *t; t = &x; sample(t);/*C'nin sanal fonksiyonu arlacak*/ } A Snfnn Sanal Fonksiyon Tablosu Sra No Adres 1 &A::fonk1() 2 &A::fonk2() B Snfnn Sanal Fonksiyon Tablosu Sra No Adres 1 &B::fonk1() 2 &B::fonk2()
72

C Snfnn Sanal Fonksiyon Tablosu Sra No Adres 1 &C::fonk1() 2 &C::fonk2() Derleyici bu mekanizmay kurabilmek iin her snfa ilikin bir sanal fonksiyon tablosu yaratr. Bu sanal fonksiyon tablolarnda ilgili snfn sanal fonksiyonlarnn adresleri bulunur. Sanal fonksiyona sahip bir snfa ilikin bir nesne tanmlandnda o nesne iin bir gizli gsterici kadar daha fazla yer ayrlr. Bu gizli gstericide nesne hangi snfa ilikinse o snfa ilikin sanal fonksiyona ilikin tablonun adresi tutulur. Bu gizli gstericinin nesnenin neresinde tutulduu standart olarak belirlenmemitir. Ancak nesnenin en dk anlaml adreslerinde genel olarak tutulmaktadr. Bu durumda bir sanal fonksiyon arldnda aa seviyeli u ilemler yaplr: 1. Sanal fonksiyon tablo gstericisi alnr ve tablonun yeri bulunur. 2. Sanal fonksiyon tablosunda ilgili sanal fonksiyonun adresi bulunur. 3. Sanal fonksiyon arlr. Sanal fonksiyon armann yer ve zaman maliyeti sz konusudur. nk sanal fonksiyon tablolar ve nesne ierisindeki sanal fonksiyon tablo gstericisi ek yer kaplamaktadr. Ayrca tablolara bakarak sanal fonksiyon arld iin ek makina komutlarna gereksinim duyulur. Bu da zaman kaybna sebep olur. Operatr Fonksiyolar C'de iki yap deikeni birbirleriyle aritmetik ilemlere ve karlatrma ilemlerine sokulamaz. Ancak ayn trden iki yap deikeni birbirlerine atanabilir. C'de olmayan bir veri tr zerinde ilem yapabilmek iin o veri tr nce bir yap ile temsil edilir. Sonra ilemler yapan arabirim fonksiyonlar yazlr. typedef struct _COMPLEX { double real, image; } COMLEX; void AddComp(COMPLEX *p1, COMPLEX *p2, COMPLEX *result); COMPLEX a = {3, 4}, b = {8, 2}, c; AddComp(&a, &b, &c); C++'ta operatr fonksiyonlar ya bir snfn ye fonksiyonu biiminde yaplr, ya da global fonksiyon biiminde olur.

73

ye Fonksiyon Biiminde Tanmlanan Operatr Fonksiyonlar Genel Biimi: [geri dn deeri] operator <operatr sembol> ([parametreler]); Operatr fonksiyonlar aslnda normal fonksiyonlardr. Yalnzca fonksiyon ismi olarak operator anahtar szc ile operatr sembol gelir. /*-----operfonk.cpp-----*/ #include <stdio.h> class A { int a; public: A(int x) { a = x; } int operator +(int x); }; int A::operator +(int x) { return a + x; } void main(void) { A n(5); int z; z = n.operator +(2); printf("%d\n", z); } /*------------------------*/ Operatr sembolne ilikin yazlan operatr fonksiyonu eer binary bir operatre ilikinse bir parametreye sahip olmas, unary bir operatre ilikinse parametreye sahip olmamas gerekir. Bir operatr fonksiyonunun ksa biimde arlmas da sz konusudur. "a.operator <sembol>(b)" ile "a <sembol> b" edeerdir. Zaten operatr fonksiyonlarnn kullanlma amac onlar ksa biimde ararak sanki normal bir operatr ilemi yaplyormu gibi okunabilirlii arttrmaktr. C++ Derleciyilerinin fadeleri Yorumlama Biimi C++ derleyicileri bir operatrle karlatnda nce operandlarn trlerini aratrr. Eer operandlar C'nin normal trlerine ilikinse ilemi normal olarak gerekletirir. Eer operandlardan biri bir snfa ilikinse uygun bir operatr fonksiyonu aratrr. yle bir operatr fonksiyonu bulursa arr.
74

Bulamazsa ilem error ile sonulandrlr. Farkl parametre yaplarna sahip ayn sembole ilikin operatr fonksiyonlar bulunabilir. Snfn Dosya Organizasyonu Normal olarak bir snf iki dosya halinde yazlr. Header dosyas ierisine snf bildirimi sembolik sabitler ve eitli bildirimler yerletirilir. Bu balk dosyasna tipik olarak #ifndef _SM_H_ #define _SM_H_ #endif biiminde eitli bildirimler yerletirilir. Bunun dnda inline fonksiyonlar da buraya yerletirilmelidir. CPP dosyasnn ierisine snfn btn ye fonksiyonlarnn tanmlamalar yazlr. Bu dosya ierisinden header file include edilir. CPP derlenerek library ierisine yerletirilebilir. Ancak bu snf baka yerlerden kullanlacaksa header dosyasnn kullanan kod ierisinde include edilmesi gerekir. Bir snfn ye fonksiyonlarnn hepsi library ierisine yerletirilebilir. Ancak derleme aamasnda header dosyasnn derleyicinin bilgilendirilmesi iin bulundurulmas gerekir. Karlatrma Operatrlerine likin Operatr Fonksiyonlarnn Yazlmas Karlatrma operatrlerine ilikin operatr fonksionlarnn parametreleri ya da geri dn deerleri herhangibir biimde olabilir. Ancak geri dn deerlerinin int trnden olmas ve koul salanyorsa 1 deerine, salanmyorsa 0 deerine geri dnmesi en uygun olab durumdur. /*-----date.h-----*/ /*-----date.cpp-----*/ CString Snfnda Karlatrma Operatr Fonksiyonlarnn Kullanlmas Yaz ilemlerini yapan CString snf yazlarn karlatrlmas iin bir grup karlatrma operatr fonksiyonuna sahip olabilir. /*-----cstring.h-----*/ /*-----cstring.cpp-----*/ +, -, *, / Operatrlerine likin Operatr Fonksiyonlarn Bu operatr fonksiyonlarnn parametreleri ve geri dn deerleri herhangi bir biimde olabilir. Ancak en ok karlalan durum fonksiyonun bir snfa geri dnmesi durumudur. Bir fonksiyonun bir snf nesnesiyle geri
75

dnmesi C'de fonksiyonun bir yapya geri dnmesi anlamna gelir. C'de fonksiyonlar yaplarn kendisine geri dnebilirler. Bu durumda bu fonksiyonlarn geri dn deerlerinin ayn trden bir yap deikenine atanmas gerekir. C'de bu durum ok rastlanan ve tavisye edilen bir durum deildir. Ancak C++'ta bu durum yani bir fonksiyonun bir snfn kendisine geri dnmesi durumu ok rastlanan bir durumdur. Byle bir fonksiyonun geri dn deeri ayn trden bir snf nesnesine atanmaldr. nk C+ +'ta ayn trden iki snf nesnesi birbirine atanabilir. /*-----complex.cpp-----*/ ++ ve -- Operatrlerine likin Operatr Fonksiyonlar Bu operatrler tek operandl olduklar iin bu operatrlere ilikin operatr fonksiyonlarnn da parametresiz yazlmas gerekir. Geri dn deerleri herhangi bir trden olabilse de en ok rastlanan durum fonksiyonun *this ile geri dnmesi ve geri dn deerinin de kendi snf trnden bir referans olmasdr. Bu operatrlerin prefix version'lar parametre parantezi ierisi void yazlarak veya bo braklarak yazlr. Postfix verison'u iin parametre parantezinin ierisine int anahtar szc yazlarak braklr. Buradaki int anahtar szc parametre anlamna gelmez. Zaten yanna deiken ismi de yazlmaz. Operatrn postfix kullanlacana ilikin bir gsterim biimidir. ++ ve -- Operatrlerinin Tarih Snfnda Kullanlmas Bu operatr fonksiyonlarnn yazm iin 1-1-1900'den geen gn saysn tarih bilgisine eviren bir fonksiyona gereksinim vardr. ++ ve -- operatr fonksiyonlarn yazmak iin RevDays() fonksiyonundan faydalanabiliriz. Eer bu operator fonksiyonlarnn yalnzca prefix version'lar yazlrsa postfix iin de kullanlabilir. Yani postfix kullanmda ayn operatr fonksiyonu arlacaktr. Postfix verison'lar yazlsa bile arttrma ileminin ifadenin sonunda yaplmasn programc salamak zorundadr. /*-----date.h-----*/ /*Ekleme Revdays(), ++, -- */ /*-----date.cpp-----*/ new ve delete Operatr Fonksiyonlarnn Yazm new ve delete operatr fonksiyonlar bir snfn ye fonksiyonlar biiminde yazlabilir. Bu durumda bir snf trnden bir tahsisat yapldnda ya da tahsis edilmi bir alan serbest brakldnda bu snfn ye fonksiyonlaryla ilgili ilemler yrtlr. new operatr fonksiyonu aadaki gibi tanmlanmak zorundadr. void * operator new(size_t size); size_t yerine unsigned int de yazlabilir ama bu tr aslnda derleyicileri yazanlar tarafndan herhangi bir tr olarak tanmlanabilecek bir tr
76

belirtmektedir. Hemen hemen btn derleyicilerde size_t unsigned int anlamndadr. Benzer biimde delete operatr fonksiyonu da u ekilde yazlmak zorundadr. void operator delete(void *ptr); /*-----opernew.cpp-----*/ Bir snfn new ve delete operatr fonksiyonlar yazlmsa bu snf trnden yaplan new ve delete ilemlerinde bu operatr fonksiyonlar kullanlr. Ama yine normal olarak balang ve biti fonksiyonlar arlacaktr. Benzer biimde snfa ilikin birden fazla snf nesnesi iin tahsisat yapabilmek iin keli parantezli operatr fonksiyonlar da yazlabilir. Keli parantezli new ve delete operatr fonksiyonlar yle bildirilmek zorundadr. void * operator new [](unsigned size); void operator delete [](void *ptr); new X[10];/*default constructor arlr*/ Global Operatr Fonksiyonlar Normal olarak x bir snf nesnesi n de C'nin normal trlerine ilikin bir nesne olmak zere x + n gibi bir ilem snfn uygun bir + operatr fonksiyonuyla gerekletirilebilir. Oysa n + x gibi bir ilem + operatrnn deime zellii olmasna ramen gerekletirilemez. nk bu ilem n.operator(x) anlamna gelir, bu da mmkn deildir. Global operatr fonksiyonlar bu durumu mmkn hale getirmek iin tasarlanmtr ve ye operatr fonksiyonlarn ilevsel bakmdan kapsar. Global operatr fonksiyonu normal bir global fonksiyon gibi yazlr. Ama operatr sembol binary bir operatre ilikinse iki parametre, unary bir operatre ilikinse tek parametre almak zorundadr. Global Operatr Fonksiyonlarnn Date Snfyla likin Uygulamalar /*-----date.h-----*//*ekleme yapld*/ /*-----date.cpp-----*/ Derleyici bir kullanm biimine uyguna hem ye operatr fonksiyonlarn hem de global operatr fonksiyonlarn aratrr. Eer her ikisi de varsa bu durum bir iki anlamllk hatas oluturur. ye operatr fonksiyonu olarak yazlabilen tm operatr fonksiyonlar global operatr fonksiyonu olarak da yazlabilir. Genellikle global operatr fonksiyonlar kolay eriim bakmndan arkada operatr fonksiyon biiminde yazlr. /*-----cstring.h-----*//*ekleme yapld*/ /*-----cstring.cpp-----*/
77

Global new ve delete Operatr Fonksiyonlar Aslnda new ve delete ilemi yapldnda arlacak global operatr fonksiyonu vardr ve bu fonksiyon derleyiciyi yazanlar tarafndan ktphane ierisine yerletirilmitir. Eer programc bu operatr fonksiyonlarn yeniden yazarsa ktphanedeki deil programcnn yazd arlacaktr. new ve delete operatr fonksiyonlar aadaki prototipe uygun yazlmak zorundadr. void * operator new(unsigned size); void * operator new [](unsigned size); void operator delete(void *ptr); void operator delete [](void *ptr); /*-----glop_new.cpp-----*/ Derleyici global new operatr fonksiyonuna parametreyi new kullanmndaki tahsisat miktar olarak geirir. Yani rnein: operatrnn

p = new int; ile p = operator new(sizeof(int)); arasnda fark yoktur. New operatr kullanldnda aslnda derleyici ifadeyi global new operatr fonksiyonunu arma ifadesine dntrr. Aslnda new bir fonksiyon arma ilemi anlamna gelir. Ktphane ierisinde new ve delete operatr fonksiyonlarnn keli parantezli fonksiyonlar da vardr. Ancak bunlar global keli parantezsiz new ve delete operatr fonksiyonlarn arrlar. void * operator [] (unsigned size) { .... p = operator new(sizeof(size)); .... } Biz keli parantezli new ve delete operatr fonsksiyonlarn yazmasak bile yazdmz new ve delete operatr fonksiyonlar yine arlacaktr. new int[n]; ilemi ile operator new [](sizeof(int) * n); ayndr. Eski derleyicilerde(borland v3.1 gibi) new ve delete operatrlerinin keli parantezli versionlarna ilikin operatr fonksiyonlarn yazmak geerli deildir. Balang Fonksiyonu le Nesne Yaratlmas C++'ta X bir snf ismi olmak zere balang fonksiyonu aryormu gibi X(...) ifadesi ile derleyici X snf trnden geici bir nesne yaratr. Bu nesne iin uygun constructor fonksiyonunu arr. fade bitince bu nesneyi
78

serbest brakarak biti fonksiyonunu arr. rnein: a = X( ) + n; ileminde nce X snf trnden geisi bir nesne tanmlanr. Sonra bu nesne + operatr fonksiyonuyla ilem grr ve a nesnesine atanr. Yaratlm olan geisi nesneye ilikin biti fonksiyonu ifadenin bitmesiyle arlacaktr. rnein: Create(...., CRect(10, 10, 20, fonksiyonunun arlmasdr*/ 20), ....);/*Buradaki ilem Create

Burada nce CRect trnden geici bir snf nesnesi yaratlr, Create fonksiyonuna parametre olarak geirilir, CReate fonksiyonu bitince yaratlan geici nesne iin destructor arlr. Tr Dntrme Operatr Fonksiyonu Bu fonksiyon yalnzca snfn ye fonksiyonu biiminde yazlabilir. Global olarak yazlamaz. Genel biimi: operator <tr> (void); Tr dntrme operatr fonksiyonlarnn geri dn gibi bir kavram yoktur(tpk balang ve biti fonksiyonlar gibi). Parametresi void olmak zorundadr. C'de ve C++'ta tr dntrme ilemi 3 biimde yaplr: 1. Atama ilemi ile(sa taraf deeri sol taraf dntrlerek atama ilemi gerekletirilir), 2. Tr dntrme operatryle, 3. lem ncesi otomatik tr dntrmeleri biiminde. deerinin trne

Bir snf baka bir snfa ya da C'nin normal trlerine dntrlecei zaman snfn ilgili tre ilikin tr dntrme operatr varsa arlarak ilemler gerekletirilir. /*-----complex.cpp-----*/ /*Ekleme yapld*/ Tr dntrme operatr fonksiyonlarnn geri dn deerleri synatx ierisinde belirtilmemi olsa da aslnda geri dn deerleri vardr ve bu tr operatr fonksiyonunun ilikin olduu trdr. Bir snfn ifade ierisinde baka bir tre dntrlmesi gerektiinde derleyici nce ilgili tre dntrme operatr fonksiyonunun olup olmadn kontrol eder. Varsa ilemini bu operatr fonksiyonunu ararak yapar. Tr dntrme operatr fonksiyonu ile snf herhangi bir trden herhangi bir adrese de dntrlebilir. /*-----cstring.h-----*/ /*-----cstring.cpp-----*/ /*Ekleme yapld*/

Tr Dntrme Operatr Fonksiyonlarnda ki Anlamllk Durumu


79

C'nin normal trlerinde dnm yapan tek bir dntrme yapan fonksiyonu varsa Bu fonksiyon kullanlarak her tre dnm yaplmas salanabilir. rnein Complex snfnn yalnzca double trne dnm yapan bir operatr fonksiyonu varsa aadaki kod hataya yol amaz: Complex b; int a; a = b; Bu rnekte eer Complex snfnn hem double hem de int trne dnm uygulayan operatr fonksiyonlar olsayd int olan seilecekti. Eer bu snfn hem double hem de long trne dnm yapan operatr fonksiyonlar olsayd bu ilem iki anlamllk hatasna yol aard. Bir snfn ayn ilemi yapabilecek hem normal bir operatr fonksiyonu hem de tr dntrme operatr fonksiyonu bir arada bulunabilir. Bu durumda normal operatr fonksiyonu ncelikli olarak ele alnr. Ancak bu tr durumlarda okunabilirlik gerei tr dntrme operatrnden faydalanlarak ilem gerekirse aka belirtilebilir. class X { public: int operator +(int x); operator int(void); }; void main(void) { X a; b = a + 10; /* + operatr fonksiyonu ile ilem yaplr*/ b = (int) a + 10; /* tr dntrme operatryle yaplr* } Balang Fonksiyonu Yoluyla Dntrme Yaplmas C'nin normal trlerinden snf trlerine dnm yaplabilir. rnein: class X { private: int x; public: X (int n); X operator +(X &r); } void main(void) { X n;

80

n + 10; }

/*

e deeri n + (X ) 10; veya n + X(10);

*/

Burada nce int tr X snf trne dntrlr, daha sonra n ile toplama ilemi yaplr. Bu dntrme ileminde snfn balang fonksiyonu kullanlr. Yani bu balang fonsiyonu ile geici bir nesne yaratlacak, ilem bittikten sonra snfa ilikin biti fonksiyonu arlacaktr. Aslnda (X) 10; ile X(10); ifadeleri arasnda fark yoktur. Tabii byle bir dnmn mmkn olabilmesi iin snfn tek parametreli balang fonksiyonu bulunmak zorundadr. zetle bir ilemin bir operand bir snf nesnesiyse bu ilem derleyici tarafndan 3 biimde yaplabilir: 1. Snfn ak bir biimde tanmlanm normal ve uygun bir operatr fonksiyonu ile, 2. Tr dntrme operatr fonksiyonu ile(yani snfn C'nin normal trlerine dntrlmesiyle) 3. C'nin normal trnn balang fonksiyonu yoluyla geici bir snf nesnesine dntrlmesiyle. Bu yntemlerin nn de ayn zamanda mmkn olmas halinde yaplacak en iyi ey ak bir syntax ile hangi yntemin tercih edildiinin belirtilmesidir. X a; int n; 1. a.operator + (n); 2. (int ) a + n; 3. a + (X ) n; Eer zellikle byle bir belirtme yapmamsa yukardaki ncelik sralar dikkate alnr. X a = X(n); ilemi C++'ta geerli bir ilemdir. Ancak burada iki kez nesne yaratlmaz. Yani geici nesne kesinlikle yaratlmayacaktr. Bu ilem tamamen X a(n); ilemiyle e deerdir. Tek Parametreli Balang Fonksiyonlarna Sahip Snflara likin Nesnelerin lk Deer Verilme Syntax'i le Tanmlanmas X a = b; gibi bir ilk deer verme ilemi tamamen X a(b); ile e deerdir. Bu e deerlik uradadan gelmektedir: 1. X a = b; 2. X a = X(b); 3. X a(b); rnein: CString x = "Ali"; ile CString x("Ali"); edeerdir.
81

[ ] Operatrne likin Operatr Fonksiyonunun Yazm Bu operatr fonksiyonunun geri dn deeri herhangi bir biimde olabilir, ancak geri dn deerinin referans olmas en uygun durumdur. Fonksiyonun parametresi tamsay trlerine ilikin olmak zorundadr ve keli parantez iindeki sayy belirtir. a bir snf nesnesi olmak zere; a[n] ile a.operator[](n) ayn anlama gelir. rnek: Snf kontrolnn yapld diziyi temsil eden rnek bir snf. /*-----kosedizi.cpp-----*/ Atama Operatr Fonksiyonlar ve Kopya Balang Fonksiyonu Ayn trden iki snf nesnesi birbirlerine atanabilir. Byle bir atama ileminde C'deki yaplarda olduu gibi karlkl veri elemanlar birbirlerine kopyalanr. Ancak baz snflarda ve zellikle gsterici veri elemanna sahip snflarda karlkl veri elemanlarnn atanmas istenen bir durum deildir. Byle snflarda iki snf nesnesi birbirine atandnda gsterici ierisindeki adresler birbirine atanr. Yani gsterici veri elemanlar ayn yeri gsteriri hale gelirler. Dar faaliyet alanna ilikin nesne iin biti fonksiyonu arldnda geni faaliyet alanna sahip nesnenin gsterdii alan da silinecektir. { CString x("Ali"); { CString y("Veli"); y = x; }/*Bu aamada x'in gsterdii bilgi silindiinden gsterici hatas ortaya kacaktr. */ } Oysa byle bir atama ileminde yaplacak en iyi ilem adreslerin deil adreslerin ieriinin kopyalanmas olacaktr. te bu tr uygulamalarda byle atama ilemlerinin probleme yol amamas iin atama operatr fonksiyonu yazlmaldr. Atama operatr fonksiyonu yalnzca snfn ye fonksiyonu olarak yazlabilir. Atama operatr fonksiyonunun parametresi herhangi bir trden olabilir. Ancak geri dn deerinin ayn snf trnden bir referans olmas en uygun durumdur. tasarm zorlatrmamamk amacyla void biimde de alnabilir. /*-----cstring.h-----*//*Ekleme yapld*/ /*-----cstring.cpp-----*/ Her snf iin ayrca atama operatr fonksiyonu yazlmasna gerek yoktur.
82

Kopya Balang Fonksiyonu(copy constructor) Bir snfn kendi snf trnden bir referans parametresine sahip balang fonksiyonuna kopya balang fonksiyonu denir. Kopya balang fonksiyonunun parametresi const bir referans da olabilir. Bu durumda C+ +'ta 3 tr balang fonksiyonu vardr: 1. Default balang fonksiyonu (parametresi void) 2. Kopya balang fonksiyonu (parametresi kendi snf trnden referans) 3. Sradan balang fonksiyonu (parametresi herhangi bir tr) Kopya balang fonksiyonu derleyici tarafndan 3 durumda arlr: 1. Bir snf nesnesinin kendi trnden bir snf nesnesiyle ilk deer verilerek tanmland durumlarda. rnein: X n = a;/*a X trnden bir snf nesnesi*/ 2. Bir fonksiyonun parametresi bir snf trnden nesnenin kendisiyse fonksiyon da ayn snf trnden baka bir snf nesnesinin kendisiyle arlmsa parametre deikeni kopya balang fonksiyonu arlarak oluturulur. 3. Fonksiyonun geri dn deeri bir snf trndense return ifadesiyle geici blgede nesne yaratlrken kopya balang fonksiyonu arlr. Bir snfn atama fonksiyonu ve kopya balang fonksiyonu yazlmak zorunda deildir. Eer yazlmamsa karlkl veri elemanlar birbirine atanr. Kopya balang fonksiyonunun yazlmasnn gerekesi atama operatr fonksiyonun yazlmas gerekesiyle ayndr. Yani bir snf iin atama fonksiyonunun yazlmas gerekiyorsa mutlaka kopya balang fonksiyonunun da yazlmas gerekir. Sanal Biti Fonksiyonlar(virtual destructor) Bir snfn biti fonksiyonu sanal olabilir. Aslnda ne zaman bir tretme yaplacaksa taban snfn biti fonksiyonu sanal yaplmaldr. Taban snfn biti fonksiyonu sanal yaplrsa o snftan tretilen tm snflarn biti fonksiyonlar otomatik olarak sanal kabul edilir. Normal olarak delete operatrnn operand hangi snfa ilikin bir adres ise o snfa ilikin biti fonksiyonu arlr. Ancak baz durumlarda adrese ilikin snfn biti fonksiyonu deil de nesnenin orijinaline ilikin snfn biti fonksiyonunun arlmas gerekir.

83

B snf A snfndan tretilmi olsun; { A *p; p = new B(n); delete p; } Burada normal olarak p gstericisi A snfna ilikin olduu iin delete p; ilemindeA snfnn bitii fonksiyonu arlr. Oysa B snfna ilikin biti fonksiyonunun arlmas uygun olan durumdur. te taban snf biti fonksiyonu sanal yaplrsa B snfna ilikin biti fonksiyonu arlr. Bu biti fonksiyonu kendi ierisinde zaten A snfnn biti fonksiyonunu da aracaktr. Bir snf kendisinden tretme yaplacak ekilde tasarlanyorsa mutlaka biti fonksiyonu sanal yaplmaldr. iostream Snf Sistemi Bu snf sistemi ekran, klavye ve dosya ilemleri iin tretilmi bir dizi snftan oluur.

istream snf klavye ve dosyadan okuma yapmak iin gereken veri elemanlarna ve ye fonksiyolarna sahiptir. ostream snf ise ekrana ve dosyaya bilgi yazmak iin gereken veri elemanlarna ve ye fonksiyonlarna sahiptir. ios snf okuma ve yazma ilemlerinde kullanlan temel ve ortak veri elemanlarn ve ye fonksiyonlarn bulunduran bir snftr. ostream snfnn her trden parametreye sahip bir grup << (sola shift) operatr fonksiyonu vardr. Bu operatr fonksiyonlar parametreleri ile belirtileni ekrana yazdrrlar. Yani ostream snf trnden bir snf nesnesi tanmlanr ve bu operatr fonksiyonlar kullanlrsa ekrana yazdrma yaplabilir.

84

ostream x; x << 100; Ancak zaten ktphane ierisinde cout isimli bir nesne tanmlanmtr. Yani bu nesne kullanlarak ekrana yazdrma yaplabilir. iostream snf sisteminin btn bildirimler iostream.h ierisindedir. Snflarn ye fonksiyonlar ktphane ierisindedir. Ostream snfnn << operatr fonksiyonlarnn geri dn deerleri yine ostream trnden bir referanstr. Bylece bu operatr fonksiyonu birden fazla eleman iin kombine edilebilir. /*-----cout.cpp-----*/ #include <iostream.h> void main(void) { int a = 123; cout << "Value=" << 20 << '\n'; } /*-------------------*/ Snf erisinde Baka Bir Snf, Yap, typedef ve enum Bildirimlerinin Bulunmas Bir snfn ierisinde yap, baka bir snf, enum vs. bildirimleri yaplabilir. Genel olarak snf ierisinde bildirilen btn deiken isimleri(yap, snf, enum sabitleri gibi) dardan ancak znrlk operatr kullanlarak snf ismiyle eriilebilir. Tabii bu eriimin geerli olabilmesi iin bildirimin snfn public blmde yaplm olmas gerekir. Yani snf ierisinde bildirilen btn deikenler snf faaliyet alanna sahip olur. Snfn ye fonksiyonlar ierisinde dorudan, dardan ancak snf ismi ve znrlk operatryle arlabilir. class X { private: int x; public: typedef unsigned int WORD; void func(void); }; void X::fonk(void) { WORD x; } void main(void) {
85

/*Doru*/

WORD x; /*Yanl*/ X::WORD x;/*Doru*/ } iostream Snf Sisteminde Formatl Yazdrma lemleri ios snfnn protected blmnde long bir x_flags isimli bir deiken vardr. ostream snfnn << operatr fonksiyonlar x_flags deikeninin bitlerine bakarak yazdrma ileminin nasl yaplacan anlarlar. Bu deikenin deerini alan ve deikenin deerini deitiren iki public ye fonksiyonu vardr: long flags(); long flags(long); x_flags deikeninin ilgili bitlerini set edebilmek iin ios snf ierisinde btn bitleri 0 yalnzca bir biti 1 olan eitli sembolik sabitler enum sabiti biiminde tanmlanmtr. rnein bitlerden birisi yazma ileminin hex sistemde yaplp yaplmayacan belirler. O bitin set edilip eski hale getirilmesi yle yaplabilir. #include <iostream.h> void main(void) { long x; x = cout.flags(); cout.flags(x | ios::hex); cout.flags(x & ~ios::hex); }

/*hex biimde yazlmasn salar*/ /*hex biimde yazlmamasn salar*/

x_flags deikeninin uygun bitleri 1 yaplarak yazdrma ilemi eitli biimlere ekilebilir. /*-----cout2.cpp-----*/ #include <iostream.h> void main(void) { int a = 100; long x; cout << a << '\n'; x = cout.flags(); cout.flags(x & ~ios::hex | ios::hex); cout << a << '\n'; } /*--------------------*/ Burada yaplan ilemi tek aamada yapan setf isimli bir ye fonksiyon da
86

vardr. long setf(long); long unsetf(long); setf fonksiyonu nce x_flags ierisindeki deeri alr, bunu parametresiyle or ilemine sokarak ilemi bir hamlede gerekletirir. /*-----cout3.cpp-----*/ #include <iostream.h> void main(void) { int a = 100; cout << a << '\n'; cout.setf(ios::hex); cout << a << '\n'; cout.unsetf(ios::hex); cout << a << '\n'; } /*--------------------*/ ios snfnn protected x_width eleman yazma ilemi iin ka karakter alan kullanlacan belirlemekte kullanlr. Bu elemanla iliki kuran iki fonksiyon vardr. int width(void); int width(int w); Benzer biimde x_precision noktadan sonra ka basamak yazlacan belirlemekte kullanlr. /*-----cout4.cpp-----*/ #include <iostream.h> void main(void) { double x = 3.52534; cout << x << '\n'; cout.precision(10); cout << x << '\n'; } /*--------------------*/ Maniplatrler ostream snfnn << operatr fonksiyonlarndan bazlar paremetre olarak bir fonksiyon adresi alr. nceden tanmlanm ktphane ierisinde ismine
87

maniplatr denilen zel fonksiyonlar vardr. void hex(void); void dec(void); void endl(void); void setw(int x); Bu fonksiyonlarn isimleri cout nesnesiyle beraber kullanlrsa x_flags deikeni zerinde eitli set ilemleri yapar. Bylece formatlama ilemi biraz daha kolaya indirgenmi olur. /*-----cout5.cpp-----*/ #include <iostream.h> void main(void) { cout << hex << 100 << endl; cout << dec << 100 << endl; } /*--------------------*/ ostream Snfna likin << Operatr Fonksiyonlarnn stenilen Bir Snf in Yeniden Yazlmas Programcnn tasarlad bir snf kolaylkla ostream snfnn << operatr fonksiyonuyla kullanlabilir. rnein x Complex snfna ilikin bir nesne olsun, "cout << x;" ile "operator <<(cout, x);" ayn anlamdadr. O halde programc geri dn deeri ostream snfndan referans, birinci parametresi ostream trnden referans, ikinci parametresi tasarlanan snfna ilikin bir nesne olacak biimde bir << global operatr fonksiyonu yazlacak olursa cout nesnesiyle ilgili snf kullanldnda belirlenen operatr fonksiyonu arlacaktr. /*-----complex.cpp-----*/ /*Ekleme yapld*/ Tabii bu operatr fonksiyonlarnn arkada fonksiyonu biimde yazlmas eriimi kolaylatrr. /*-----date.h-----*/ /*Ekleme yapld*/ /*-----date.cpp-----*/ istream Snf ve Klavyeden Bilgi Alnmas istream snfnn bir grup referans parametresi alan >> operatr fonksiyonu vardr. Bu operatr fonksiyonlar klavyeden okuma yaparak deeri ilgili parametre deikenine aktarrlar. Global dzeyde tanmlanm istream snf trnden cin isimli bir nesne vardr. Dorudan bu nesne kullanlarak okuma yaplabilir.

88

/*-----cin.cpp-----*/ #include <iostream.h> void main(void) { int x; double y; cin >> x >> y; cout << x << " " << y << endl; } /*------------------*/ Benzer biimde programcnn tasarlad snflar iin de >> operatr fonksiyonlar da yazlabilir. Bu fonksiyonlarn geri dn deerleri istream trnden referans, birinci parametreleri istream trnden referans, ikinci parametreleri ise ilgili snf trnden referans olmaldr. iostream snf sistemi ayn zamanda dosya ilemleri iin de kullanlmaktadr. Bunlar iin fstream, ifstream ve ofstream snflar kullanlr. Genel Fonksiyonlar ve Snflar(Template lemleri) C'de pek ok durumda temel bir algoritmay altran fonksiyon tre baml olur. Yani farkl trler iin bir fonksiyondan defalarca yazmak gerekebilir. rnein bir dizinin en byk elemann bulan fonksiyon int, long, double gibi trler iin ayn biimde tekrar yazlmak zorundadr. Geri trden bamsz ilem yapabilecek algoritmalar tasarlanabilir. rnein qsort fonksiyonu her trden diziyi sraya dizebilmektedir. Ancak byle algoritmalar zel tre bal ilem yapan algoritmalara gre daha yava ve verimsiz olur. Kald ki birok algoritma zaten trden bamsz tasarlanamaz. Sonu olarak ayn fonksiyondan farkl trler iin yeniden yazmak gerekebilir. Template ilemleriyle birtakm fonksiyonlar ve snflar derleyici tarafndan farkl trler iin yeniden yazlmaktadr. Template ilemleri template fonksiyonlar ve template snflar olmak zere iki biimde yaplabilir. Template Fonksiyonlar Genel biim: template <class(typename) ismi>([parametreler]) { } rnek: template <class T> void fonk(T a)
89

T>

[geri

dn

deeri]

<fonksiyon

{ } template bir anahtar szcktr. template anahtar szcnden sonra < > gelmelidir. < > arasndaki class anahtar szcnn normal snf ilemleriyle hibir ilgilisi yoktur. class anahtra szc yerine 1996 standardizasyonunda typename anahtar szc de kullanlabilir. class anahtar szcnden sonra isimlendirme kuralna gre herhangi bir isim yazlr. Bu isim bir tr belirtir. Template fonksiyonlar ve snflar birer ablondur. Yani kendi balarna kodda yer kaplamazlar. Bir template fonksiyon arldnda derleyici nce arlma ifadesindeki parametre yapsn inceler. Bu tre uygun olarak ablonda belirtilen fonksiyondan programc iin yazar. /*-----templat.cpp-----*/ #include <iostream.h> template <class T> void fonk(T a) { cout << a << endl; } void main(void) { fonk(3.5); fonk(30L); fonk(40L); } /*----------------------*/ Template fonksiyonlarda tr belirten szce template argman denir. Template argmannn template fonksiyon parametre yaps ierisinde gzkmesi zorunludur. Zaten gzkmemesi durumu da anlamsz olur. Bu template argman geri dn deeri olarak ya da fonksiyon ierisinde tr belirten szck olarak kullanlabilir. /*-----templat2.cpp-----*/ #include <iostream.h> template <class T> T abs(T a) { return a > 0 ? a : -a; } void main(void) { cout << abs(-3.5) << endl;
90

cout << abs(-3) << endl; cout << abs(-10L) << endl; } /*------------------------*/ Bir template fonksiyon birden faazla farkl template argmanna sahip olabilir. Bu durumda pek ok kombinasyon sz konusu olabilir. /*-----templat3.cpp-----*/ #include <iostream.h> template <class A, class B> void fonk(A a, B b) { cout << a << endl << b << endl; } void main(void) { fonk(20L, 100); fonk(100, 20L); fonk(1.3, 10L); fonk('c', 12); } /*------------------------*/ Template fonksiyonlar arldnda uygun parametre yaps bulunamazsa error durumu oluabilir. /*-----templat4.cpp-----*/ #include <iostream.h> template <class T> void swap(T *a, T *b) { T temp; temp = *a; *a = *b; *b = temp; } void main(void) { int x = 10, y = 20; swap(&x, &y); cout << "x = " << x << " " << "y = " << y << endl; } /*------------------------*/

91

Bir template fonksiyon ierisinde baka bir template fonksiyon arlm olabilir. Template argman bir snf da olabilir. Bir template fonksiyonuyla ayn isimli normal bir fonksiyon bir arada bulunabilir. Bu durumda iki anlamllk hatas olumaz. Normal fonksiyonun template fonksiyona kar bir stnl vardr. Snf almas: template <class T> void sort(T *p, int size); Biiminde sort ilemi yapan bir template fonksiyonu yaznz. /*-----templat5.cpp-----*/ #include <iostream.h> template <class T> void swap(T *a, T *b) { T temp; temp = *a; *a = *b; *b = temp; } template <class T> void sort(T *p, int size) { int i = 0, j = 0; for (i = 0; i < size - 1; ++i) for (j = i + 1; j < size; ++j) if (p[i] > p[j]) swap(p + i, p + j); } void main(void) { int a[5] = {3, 8, 4, 7, 6}; int i; sort(a, 5); for(i = 0; i < 5; ++i) cout << a[i] << endl; } /*-----------------------*/ Template fonksiyonlar bir ablon belirtir ve ktphaneye yerletirilemez. Bu yzden header dosyalarnn ierisine yazlmaldr.
92

Template Snflar Template snflarda derleyici nesne tanmlama biimine uygun bir snfn ye fonksiyonlarnn hepsini yazar. Genel biimi: template <class T> class X { }; Bu template argman snf bildiriminin ierisinde ve btn ye fonksiyonlarn ierisinde tr belirten szck olarak kullanlabilir. Uygulamada arlkl bir biimde template snflar kullanlmaktadr. Bir tenplate snfa ilikin ye fonksiyon snfn dnda aadaki syntax biimine uygun yazlmak zorundadr. template <class T> [geri_dn_deeri] snf_ismi<T>::fonksiyon_ismi(parametreler) { } rnek: template <class T> void X<T>::fonk(void) { } Bir template snfa ilikin snf nesnesi yle tanmlanr: snf_ismi <tr ismi> nesne_ismi; rnek: Array <int> x; /*-----templat6.cpp-----*/ #include <stdio.h> #include <stdlib.h> template <class X> class Array { private: int size; X *p; public: Array(void); Array(int n); X & operator [](int n);
93

}; template <class X> Array<X>::Array(void) { size = 10; p = new X[size]; } template <class X> Array<X>::Array(int n) { size = n; p = new X[size]; } template <class X> X & Array<X>::operator[](int n) { if (n >= size) { printf("Out of range\n"); exit(1); } return p[n]; } void main(void) { Array <float> n(5); for (int k = 0; k < 5; ++k) n[k] = k; for (k = 0; k < 10; ++k) printf("%f\n", n[k]); } /*---------------------*/ Stack Sistemine likin Bir template Snf rnei Stack Sistemi Nedir? Stack lifo sistemi ile alan bir kuyruk yapsdr. Stack sisteminin ismine stack pointer denilen bir gstericisi vardr. Bu gsterici o anki stack pozisyonunu tutar. Stack sistemi ile ilgili iki temel ilem vardr: 1. Eleman Eklenmesi: Eleman eklenmesi durumunda nce stack gstericicsi azaltlr daha sonra stck gstericisinin gsterdii yere eleman yerletirilir. stack sistemini balang konumunda sp tahsis edilmi alann en aasn gsterir. Stack'e eleman eklenmesine push denir. Stack sistemine fazla eleman yerletirilmesi tamaya yol aabilir. Bu ileme stack sisteminin
94

sten tamas denir(stack overflow) 2. Eleman ekilmesi: Bu durumda stack gstericisinin gsterdiyi yerden eleman ekilir ve stack gstericisi bir artrlr. Stack'ten bilgi alnmasna pop ilemi denir. Eer fazla sayda eleman ekilme ilemi uygulanrsa stack aaya doru taar. Bu ileme stack underflow denir. Stack Sisteminin Uygulama Alanlar 1. Ters dz etme ilemi. Bir yazy ters dz etmek iin karakterler tek tek stack sistemine eklenir ve sonra ekilir. 2. Undo ilemleri: Stasck sisteminin her eleman yaplan ilem hakknda bilgiyi tutan bir yap eklindedir. lemler yapldka push ilemi ile stack sistemine yerletirilir. daha sonra undo yapldka pop ilemi ile geri alnr. 3. Aktif pencerenin bulunmas ilemi: stste alan pencerelerde son alan aktif penceredir o pencere kapatlrsa bir nceki pencere aktif pencere olur. /*-----stack.h-----*/ /*-----stack.cpp-----*/ nesne tanmlanrken kullanlan template tr baka bir template snf olabilir. X <Y<int>> Z; oklu Tretme (multiple inherritence) Bir snfn birden fazla taban snfa sahip olmas durumudur. oklu tretme durumunda balang fonksiyonlarnn arlmas bildirimde ilk yazlan taban snfn balang fonksiyonu nce arlacak biimdedir. rnein class C:public A, public B { byle bir bildirimde nce a, b, c eklinde balang fonksiyonlar arlr. Biti fonksiyonlarda c, b, a olacak ekilde tam tersdir. Tremi snf nesnesi btn taban snf nesnelerinide ierir. Taban snf nesnelerinin tenmi snf iindeki organizasyonu standart olarak belirlenmemitir. Ancak bildirimde genllikle bildirimde ilk yazlan taban snfn vweri elemanlar dk anlaml adreste oacak biimde ardl bir yerleim sz konusudur. /*-----multinhe.cpp-----*/ oklu Tretmede Faaliyet Alan ve sim Arama oklu tretme urumunda tremi snf btn taban snflara eriebilir. taban snflara eriim konusunda hi bir nceklik yoktur. Btn taban snflar ayn faaliyet alan iinde kabul edilir. Yani her iki taban snftada ayn isimli bir veri eleman yada ye fonksiyonu varsa ve eriim znrlk operatr ile yaplmamsa bu durum iki anlamllk hatasnn olumasna yol aar.

95

A int x; C

A B B

int x;

C n; n.x = 10; /*Bu ilem iki anlamllk hatasdr*/ Yani tremi snf ye fonksiyonu iinde bir isim kukllanldnda bu isim: 1. Tremi snf faaliyet alan iinde 2. Taban snflarn her birinin faaliyet alan iinde aranr ve bir sra gzetilmez. oklu Tretmede Tremi Snf Adresinin Taban Snf Adresine Atanmas Durumu: Mademki tremi snf nesnesinin adesi herhangibir tabna snf nesnesinin adresine atana biliyor o halde adresteki ilemler geerlidir. C x; A *pa; B *pb; pa = &x; pb = &x;/*ilemleri geerlidir*/ oklu tretme durumunda tremi snf nesnesinin adresi, herhangi bir taban snf gstericisine atandnda derleyici tremi snf nesnesinin taban snf veri elemannn adresini gstericiye atar. eitli oklu Tretme emalar 1. Bir snfn birden fazla dorudan taban snf olamaz. Baka bir deyimle bir snf baka bir snfa birden fazla taban snflk yapamaz.

/*Bu ilem olamaz.*/ class B: public A, public A { }; Byle bir bildirimde ayn snfn veri elemanlarndan iki kez oluturulur. Faaliyet alan gerei ayn isimli iki taban snf veri elemanlarna atma zlerek eriim salanamaz. !!!LERS EKSK OLABLR!!! A A
96

B D

class B::public A { //... } class C::public A{ //... } class D::public B, public C { //... }; Yukardaki gibi bir tretme mmkndr. D snf trnden bir nesne tanmlanrsa muhtemel organizasyon yle olur: A B A C D A snfnn a isminde bir public veri eleman olsun. X.a biimindeki bir eriim, ikianlamllk hatasnn olumasna yol aar. Ancak, istediimiz bir A snfnn a veri elemanna yle eriebiliriz. D x; ((B *) &x )a ((C*) &x )a X.B::a X.C::a B'nin C'nin B'nin C'nin a'sna a'sna a'sna a'sna eriilir eriilir eriilir eriilir.

Bu tr tekrarlanma durumlarnda her iki koldan ilerlendiinde farkl veri elemanna eriim salanacandan bu durum bir koldan deiikliin dier kola yansmamasna yol aar. Bu da istenen bir durum deildir. Sanal Taban Snflar Bir taban snf virtual yaplrsa (sanal yaplrsa) tremi snf nesnesi iinde o snf veri elemanlarndan yalnzca bir kopya yerletirilir. Bu durumda sol ve sa kollarn her ikisi de ayn taban snf veri elemanlar zerinde ilem yapar. class ios{ //... }

97

class istream::virtual public ios { //... } class iostream:virtual public ios{ //... } class iostream:public istream, public ostream { //... } Tretmede sanal taban snf yaplmas, yukardaki tretmeler iin fayda salamaktadr. Soyut Snflar ve Saf Sanal Fonksiyonlar Bir snfn virtual double calc p()=0; Byle fonksiyonlara saf sanal fonksiyon denir . Saf sanal fonksiyonlarn yalnzca prototip bildirimi sz konusudur. Saf sanal fonksiyonlar tanmlanamazlar. Soyut snftan tretilen snfn da sanal fonksiyon yazlmamsa bu tretilmi olan snf da soyut snf olur, bu snf trnden de nesne tanmlanamaz. Soyut Snflara neden gereksinim duyulur? Baz snflar, tretme iin bir ekillendirme ve ablon amacyla kullanlrlar. class Shape { public: virtual void Rotate (void) = 0; virtua void Shift (void) =0; }; class Triangle:public shape { }; class Rectangle: public shape { }; Bu tip snflara eitli saf sanal fonksiyonlar eklenirse bu snftan tretme yapacak olan kiiler, hangi fonksiyonlar yazmalar gerektiini anlarlar ve
98

konu onlar iin ekillendirilmi olur. Aslnda C++'da struct ile class arasnda hi bir fark yoktur. Yap da bir eit snftr. Yani snflar zerinde yaplabilen tm ilemler yaplar zerinde de yaplabilir. Ancak yaplarn default blmleri private deil public'tir (Nedeni yap ieren bir C programnn uzants .CPP yaplmas ile dorudan almasnn salanmas iindir) Ancak snf nesnelerine kme parantezleri ile ilk deer vermek mmkn olmadna gre ve yaplar da bir eit snf olduuna gre ilk deer verilmi bir yap deikeninin bulunduu bir C programnn uyumsuzlua yol amamas iin bir kural eklenmitir. Eer bir yap ya da snfn private ve protected blmleri yoksa balang ve biti fonksiyonlar yoksa, bu snftan tretme yaplmamsa, bu snf ya da yap sanal fonksiyona sahip deilse, bu tr yap ya da snflara uyumlu yap ya da snflar denir (aggregate class) . Uyumlu yap ya da snflara kme parantezi ierisinde ilk deer verilebilir. Hatalarn yakalanmas ve lenmesi (exception handling) Hata oluturabilecek bir koda karn nlem alnmas ve eer hata olumusa uygun ilemlerin yaplabilmesi C'de pek ok durumda nemli bir ilemdir. rnein ne zaman malloc arlsa baarszln test edilmesi ve buna karn bir nlem alnmas gerekir. Bazen hata oluturabilecek kodlar, ktphane ierisinde ve olduka derinlerde bulunur. Hata kayna en dtaki fonksiyona bildirilemeyebilir. Programdan ani bir biimde kmak, en dtaki fonksiyonu aran tarafndan istenmeyebilir. Derinlerdeki bir hatann en dtaki fonksiyon tarafndan tesbit edilebilmesi iin zel yntemler kullanlabilir. Bunlar tasarm zorlatrr. C++'da derinlerdeki hatalarn ele alnabilmesi iin yeni bir yntem kullanlmaktadr. yle ki, hata ne kadar derinlerde ortaya km olursa olsun programn ak programcnn istedii bir noktaya ekilebilir. C+ +'daki bu mekanizmaya ngilizcede "exception handling" denir. Exception handling konusu, C++'a greli olarak yeni eklenmi konulardan birisidir. Exception szc, zellikle sistemdeki problemler yznden ortaya km olan lmcl hatalar anlatmak iin kullanlan bir szcktr. handling szc, oluan hatalarn ilenmesi anlamndadr. C++'da hatalarn yakalanmas ve ilenmesi iin 3 anahtar szck kullanlr: try throw catch

Genel biim: try {


99

} catch (..) { } try anahtar szcnden sonra bir blok oluturmak zorunludur. Buna try blou denir. Catch anahtar szcnden sonra bir blok oluturulur, buna da catch blou denir. Catch blou try bloundan hemen sonra oluturulmak zorundadr. Catch blou hata olutuunda programn aknn geirilecei noktay belirler. try blou, hangi blgede ortaya kan hatalarn ele alnacan belirlemekte kullanlr. Her catch blou bir try blouna ilikin olmak zorundadr. Try blou programn alma zamanna ilikin aksal bir alan belirtir. Yani, ret blounun ierisinde bir fonksiyon arlm olsa, o fonksiyonlar da baka fonksiyonlar ararak derinlere inilmi olsa, ak yine try blounun ierisinde kabul edilir, ve hata olutuunda ak o try blouna ilikin catch blouna ynlendirilir. Catch Blounun Organizasyonu Bir try blouna ilikin birden fazla catch blou olabilir. (Bunlarn peisra gitmesi gereklidir ) Catch bloklarnn bir tane parametresi olur. Catch parantezinde yalnzca parametre tr belirtilebilir, parametre deikeni ad verilmeyebilir catch (int) Throw anahtar szc hata olutuunda programn akn catch blouna ynlendirmek iin kullanlr. Kullanm: throw [ifade] Derleyici, throw anahtar szcnn yanndaki ifadenin trn tesbit eder, bu tre uygun bir catch blou varsa programn akn o catch blouna ynlendirir, yoksa "abort" fonksiyonunu ararak program bitirir. Abort fonksiyonu, bir takm geri alma ilemlerini yapmadan program sonlandrr ve ekrana "abnormal program termination" yazsn kararak bitirir. Throw ilemi bir goto ilemi gibidir, yani ak catch blouna geer ve daha sonra catch blounun altndan devam eder, geriye dnmez. Throw anahtar szc, ak bakmndan bir try blounun ierisinde kullanlmamsa, bu durumda derleyici abort fonksiyonunu ararak program sonlandrr. Yani try blou kurmadan bir throw ilemi yakalanrsa program yine abort fonksiyonu ile kesilir. ie try ve catch bloklar sz konusu olabilir. Bu durumda throw ilemi ile en yakn catch blouna gidilir. Throw'un yanna bir ifade yazlmazsa, ak bir nceki throw ifadesinde
100

olduu gibi ayn biimde bir dtaki catch blouna ynlendirilir. Catch parantezi ierisine nokta (elipsis) konursa bu tm throwlar al demektir. nokta ifadeli catch bloklar dier bloklarla birlikte bulunabilir. Hatalarn Snflarla ele alnmas class Exception { }; void main (void) { try{ ... throw Exception (...); } catch (Exception &r) { ... } } ... Uygulamada en sk raslanan durum throw anahtar szcnn bir snf nesnesi ile birlikte kullanlmas, ve hatalarn da bu snf tarafndan ele alnmasdr

101

You might also like