Title: NESNEYE Y
1NESNEYE YÖNELIK PROGRAMLAMASANAL
FONKSIYONLARVE ÇOK BIÇIMLILIK
Özlem AYDIN Trakya Üniversitesi Bilgisayar
Mühendisligi Bölümü
Not Bu sunumda Doç. Dr. Yilmaz KILIÇASLANin
Nesneye Yönelik Programlama dersi sunumlarindan
faydalanilmistir.
2GIRIS
- C, hem derleyici-zamanli hem de çalisma-zamanli
çok biçimliligi destekler. - Derleyici-zamanli çok biçimlilik fonksiyonlarin
veya operatörlerin asiri yüklenmesi yoluyla
gerçeklestirilir. - Çalisma-zamanli çok biçimlilik ise kalitim ve
sanal fonksiyon mekanizmalari araciligiyla
gerçeklestirilir.
3SINIF HIYERARSISI
- Dört sinif arasinda tanimlamis oldugumuz kalitim
iliskisi sematik olarak asagidaki gibi
gösterilebilir
4TEMEL VE TÜRETILMIS SINIFLAR ARASINDA DÖNÜSÜM - 1
- Bir satis elemaninin ayni zamanda bir ücretli
çalisan olmasi nedeniyle, bir UcretliCalisan
nesnesine ihtiyaç duydugumuz zaman bir
SatisElemani nesnesi kullanabiliyor olmamiz
anlamli olacaktir. Bu tarz bir iliskiyi
desteklemek için, C örtük olarak bir türetilmis
sinif nesnesini bir temel sinif nesnesine
dönüstürür - UcretliCalisan isci
- SatisElemani satici( Ali Uzun )
- isci satici //SatisElemani gt UcretliCalisan
- //turetilmis gt temel
- Ters yönlü bir atama kabul edilmeyecektir
- satici isci // Error cannot convert
-
5TEMEL VE TÜRETILMIS SINIFLAR ARASINDA DÖNÜSÜM - 2
- Benzer sekilde, türetilmis bir sinif nesnesine
isaret eden bir isaretçi örtük olarak bir temel
sinif nesnesine isaret eden bir isaretçiye
dönüstürülebilir - Calisan cPtr
- UcretliCalisan isci( Oya Kiper )
- SatisElemani satici( Ali Uzun )
- Yonetici mudur( Mehmet Demir )
- cPtr isci //UcretliCalisan gt Calisan
- cPtr satici //SatisElemani gt Calisan
- cPtr mudur //Yonetici gt Calisan
-
6TEMEL VE TÜRETILMIS SINIFLAR ARASINDA DÖNÜSÜM - 3
- Bir nesneye isaretçi ile referansta bulunuldugu
zaman hangi eleman fonksiyonun çagrilacagini
isaretçinin tipi belirler. Eger bir türetilmis
sinif nesnesine bir temel sinif isaretçisi ile
isaret ederseniz yalnizca temel sinifa ait
fonksiyonlari çagirabilirsiniz - SatisElemani satici( Ali Uzun )
- SatisElemani sPtr
- UcretliCalisan uPtr
- sPtr satici
- uPtr satici
- uPtr-gtsureBelirle(40.0) //UcretliCalisan
- sPtr-gtucretBelirle(6.0) //UcretliCalisan
- uPtr-gtsatislariBelirle(1000.0) //Error
- sPtr-gtsatislariBelirle(1000.0) //SatisElemani
- sPtr-gtkomisyonBelirle(0.05) //SatisElemani
- float taban, toplam
- taban uPtr-gtodemeHesapla() //UcretliCalisan
- toplam sPtr-gtodemeHesapla() //SatisElemani
-
7TEMEL VE TÜRETILMIS SINIFLAR ARASINDA DÖNÜSÜM - 4
- Türetilmis bir sinif isaretçisinin bir temel
sinif isaretçisine dönüstürülebilmesi, örnegin,
bir çalisanlar toplulugu olusturmamiza imkan
verebilir - class PersonelListesi
- public
- PersonelListesi()
- ekle( Calisan yeniPer )
- //
-
-
8TEMEL VE TÜRETILMIS SINIFLAR ARASINDA DÖNÜSÜM - 5
- PersonelListesi bolum1
- UcretliCalisan ucretliPtr
- SatisElemani saticiPtr
- Yonetici yoneticiPtr
- // Yeni nesneler için bellek talebi
- ucretliPtr new UcretliCalisan(Ayse Suer )
- saticiPtr new SatisElemani( Ali Demir )
- yoneticiPtr new Yonetici( Mehmet Yilmaz )
-
- // Listeye ekleme
- bolum1.ekle( ucretliPtr )
- bolum1.ekle( saticiPtr )
- bolum1.ekle( yoneticiPtr )
- Buradaki sorun her nesne yalnizca genel bir
Calisan düzeyinde isleme tabi olabilir.
9SANAL FONKSIYONLAR (sentaks)
- Sanal fonksiyon temel bir sinifta bildirimi
yapilan fakat türetilmis bir sinifta yeniden
tanimlanmasini bekledigimiz bir eleman
fonksiyondur. - Bir sanal fonksiyon bildirimi temel siniftaki
eleman fonksiyon bildiriminin öncesine virtual
anahtar sözcügünü yerlestirerek gerçeklestirilir. - Global fonksiyonlar, arkadas fonksiyonlar ve
statik eleman fonksiyonlar sanal fonksiyon
olamazlar. - virtual anahtar sözcügü, türetilmis siniflardaki
bildirimler ya da sinif disinda tanimlanmis sanal
fonksiyonlar için gerekli degildir bir sanal
fonksiyonun türetilmis siniflardaki versiyonlari
örtük olarak sanal bildirimlidirler. - Türetilmis siniftaki sanal fonksiyon bildiriminde
ya da sinif disindaki sanal fonksiyon taniminda
virtual anahtar sözcügünü kullanmak derleyici
tarafindan bir hata olarak yorumlanmaz.
10SANAL FONKSIYONLAR (semantik)
- Normal bir erisimde, sanal fonksiyonlar diger
bütün sinifa ait eleman fonksiyonlar gibi
davranirlar. Fakat, sanal fonksiyonlari önemli
kilan ve çalisma zamanli çok biçimliligi
desteklemesini saglayan bir isaretçi ya da
referans ile erisilmeleri halindeki
davranislaridir. - Eger bir temel sinif isaretçisi ya da referansi
bu temel siniftan türetilmis bir sinifin
nesnesine isaret ediyorsa / referansta
bulunuyorsa, siradan fonksiyonlarda olmasini
bekledigimizin tersine, C sanal bir fonksiyonun
hangi versiyonunu çagiracagina nesneye bakarak
karar verir. - Bu karar çalisma zamaninda gerçeklestirilir.
- Dolayisiyla, farkli nesnelere isaret edildiginde
/ referansta bulunuldugunda fonksiyonun farkli
versiyonlari çalistirilacaktir.
11SANAL FONKSIYONLAR (örnek)
- //Sanal odemeHesapla fonksiyonlu calisan sinif
hiyerarsisi - class Calisan
- public
- Calisan( const char nm )
- char isimSoyle() const
- virtual float odemeHesapla() const
- virtual Calisan()
- private
- char isim30
- class UcretliCalisan public Calisan
- public
- UcretliCalisan( const char nm )
- void ucretBelirle( float ucrt )
- void sureBelirle( float st )
- float odemeHesapla() const // sanal (ortuk)
- private
- float ucret
12SANAL FONKSIYONLAR (örnek)
- class SatisElemani public UcretliCalisan
- public
- SatisElemani( const char nm )
- void komisyonBelirle( float kom )
- void satislariBelirle( float satislar )
- float odemeHesapla() const // sanal (ortuk)
- private
- float komisyon
- float satisMiktari
- class Yonetici Calisan
- public
- Yonetici( const char nm )
- void maasBelirle( float maas )
- float odemeHesapla() const // sanal (ortuk)
- private
- float haftalikMaas
13SANAL FONKSIYONLAR (örnek)
- Her sinifin kendisine ait odemeHesapla
fonksiyonunun tanimi degismeden kalabilir. Fakat,
temel sinifa eklenen odemeHesapla fonksiyonu için
bir tanim gerekmektedir - float CalisanodemeHesapla() const
- cout ltlt Hesaplama islemi tanimlanmamis\n
- return 0.0
- Bu fonksiyon eger salt bir Calisan nesnesi
kullanildiginda ya da türetilmis siniflardan bir
tanesi kendi odemeHesapla fonksiyonunu
tanimlamamis ise çagrilir.
14SANAL FONKSIYONLAR (örnek)
- // Bir Calisan isaretcisi ile odemeHesapla
cagrimi - Calisan cPtr
- float ucret
- cPtr isci
- ucret cPtr-gtodemeHesapla() //UcretliCalisan
- cPtr satici
- ucret cPtr-gtodemeHesapla() //SatisElemani
- cPtr mudur
- ucret cPtr-gtodemeHesapla() //Yonetici
- Eger odemeHesapla sanal bildirimli olmasaydi,
her fonksiyon çagrimi, 0.0 degerini döndüren
CalisanodemeHesapla fonksiyonunu
çalistiracakti. Fakat, verilen çagrimlarin ayni
olmasina ragmen çalistirilacak fonksiyonlar
farkli olacaktir.
15SANAL FONKSIYONLAR (örnek)
- // Bir baska ornek
- include ltiostreamgt
- using namespace std
- class temel
- public
- virtual void sanalFonk()
- cout ltlt Temel sinif sanalFonk\n
-
- class turetilmis1 public temel
- public
- void sanalFonk()
- cout ltlt Turetilmis sinif1 sanalFonk\n
-
- class turetilmis2 public temel
- public
- void sanalFonk()
16SANAL FONKSIYONLAR (örnek)
- int main()
-
- temel p, b
- turetilmis1 d1
- turetilmis2 d2
- p b
- p-gtsanalFonk()
- p d1
- p-gtsanalFonk()
- p d2
- p-gtsanalFonk()
- return 0
-
- Program çiktisini belirleyiniz.
17SANAL FONKSIYONLAR (örnek)
- Program çiktisi
- Temel sinif sanalFonk
- Turetilmis sinif1 sanalFonk
- Turetilmis sinif2 sanalFonk
- Normal yolla sanal fonksiyon çagrimi
- d2.sanalFonk // turetilmis2sanalFonk
18SANAL FONKSIYONLAR ve REFERANSLAR - 1
- // Temel sinif referansi ile sanal fonksiyon
erisimi - include ltiostreamgt
- using namespace std
- class temel
- public
- virtual void sanalFonk()
- cout ltlt Temel sinif sanalFonk\n
-
- class turetilmis1 public temel
- public
- void sanalFonk()
- cout ltlt Turetilmis sinif1 sanalFonk\n
-
- class turetilmis2 public temel
- public
- void sanalFonk()
19SANAL FONKSIYONLAR ve REFERANSLAR - 2
- // Temel sinif referansini parametre alan
fonksiyon - void f(temel r)
- r.sanalFonk()
- int main()
-
- temel b
- turetilmis1 d1
- turetilmis2 d2
- f(b)
- f(d1)
- f(d2)
- return 0
-
- Program çiktisini belirleyiniz.
20SANALLIK KALITIMLA AKTARILIR - 1
- Sanal bir fonksiyon kalitildiginda, sanal dogasi
da kalitilir - include ltiostreamgt
- using namespace std
- class temel
- public
- virtual void sanalFonk()
- cout ltlt Temel sinif sanalFonk\n
-
- class turetilmis1 public temel
- public
- void sanalFonk()
- cout ltlt Turetilmis sinif1 sanalFonk\n
-
- class turetilmis2 public turetilmis1
- public
21SANALLIK KALITIMLA AKTARILIR - 2
- int main()
-
- temel p, b
- turetilmis1 d1
- turetilmis2 d2
- p b
- p-gtsanalFonk()
- p d1
- p-gtsanalFonk()
- p d2
- p-gtsanalFonk()
- return 0
-
- Bu kez, turetilmis2 adli sinif temel adli
siniftan degil turetilmis1 adli siniftan
türetilmistir ama sanalFonk yine sanal kalmistir.
Program çiktisini belirleyiniz.
22SANAL FONKSIYONLAR HIYERARSIKTIR - 1
- Eger türetilmis bir sinif sanal bir fonksiyonu
yeniden tanimlamaz ise bu sinifin bir nesnesi
sanal fonksiyona erismek istediginde temel sinif
tarafindan tanimlanan versiyon kullanilir - include ltiostreamgt
- using namespace std
- class temel
- public
- virtual void sanalFonk()
- cout ltlt Temel sinif sanalFonk\n
-
- class turetilmis1 public temel
- public
- void sanalFonk()
- cout ltlt Turetilmis sinif1 sanalFonk\n
-
- class turetilmis2 public temel
- public
23SANAL FONKSIYONLAR HIYERARSIKTIR - 2
- int main()
-
- temel p, b
- turetilmis1 d1
- turetilmis2 d2
- p b
- p-gtsanalFonk()
- p d1
- p-gtsanalFonk()
- p d2
- p-gtsanalFonk()
- return 0
-
- Program çiktisini belirleyiniz.
24SANAL FONKSIYONLAR HIYERARSIKTIR - 3
- Program çiktisi
- Temel sinif sanalFonk
- Turetilmis sinif1 sanalFonk
- Temel sinif sanalFonk
- Yukaridaki program genel bir kuralin özel bir
durumunu örneklemektedir. Kalitim, Cda
hiyerarsik olarak tanimlandigi için, sanal
fonksiyonlar da hiyerarsik olmalidir. Bu ise,
eger türetilmis sinif sanal fonksiyonu yeniden
tanimlamis ise tersinden hiyerarsik siralamada
ilk yeniden tanimlanmis fonksiyonun kullanilacagi
anlamina gelir (bkz. bir sonraki örnek).
25SANAL FONKSIYONLAR HIYERARSIKTIR - 4
- include ltiostreamgt
- using namespace std
- class temel
- public
- virtual void sanalFonk()
- cout ltlt Temel sinif sanalFonk\n
-
- class turetilmis1 public temel
- public
- void sanalFonk()
- cout ltlt Turetilmis sinif1 sanalFonk\n
-
- class turetilmis2 public turetilmis1
- public
- // sanalFonk() yeniden tanimlanmamis.
26SANAL FONKSIYONLAR HIYERARSIKTIR - 5
- int main()
-
- temel p, b
- turetilmis1 d1
- turetilmis2 d2
- p b
- p-gtsanalFonk()
- p d1
- p-gtsanalFonk()
- p d2
- p-gtsanalFonk()
- return 0
-
- Program çiktisini belirleyiniz.
27SANAL FONKSIYONLAR HIYERARSIKTIR - 6
- Program çiktisi
- Temel sinif sanalFonk
- Turetilmis sinif1 sanalFonk
- Turetilmis sinif1 sanalFonk
28SAF SANAL FONKSIYONLAR - 1
- Birçok durumda temel siniftaki sanal fonksiyon
için anlamli bir tanim bulunmayabilir. Bu
durumlarda saf sanal fonksiyonlar (pure virtual
functions) kullanilir. - Saf sanal fonksiyon temel sinifta tanimi olmayan
sanal fonksiyondur ve bildiriminin genel formu
asagidaki gibidir - virtual tip fonksiyon-ismi(parametreler) 0
- Saf sanal fonksiyon türetilmis bütün siniflarda
yeniden tanimlanmalidir. Aksi, derleyici-zamanli
hataya yol açar. - En az bir saf sanal fonksiyon içeren sinifa soyut
(abstract) sinif denir. - Soyut siniflara ait nesne yaratilamaz ama soyut
siniflara isaret eden isaretçiler ya da
referansta bulunan referanslar yaratilabilir.
29SAF SANAL FONKSIYONLAR - 2
- include ltiostreamgt
- using namespace std
- class sayi
- protected
- int deger
- public
- void degerBelirle(int i) deger i
- virtual void goruntule() 0
-
- class hexTip public sayi
- public
- void goruntule() cout ltlt hex ltlt deger ltlt
\n -
- class desTip public sayi
- public
- void goruntule() cout ltlt deger ltlt \n
30SAF SANAL FONKSIYONLAR - 3
- int main()
-
- desTip d
- hexTip h
- oktTip o
- d.degerBelirle(20)
- d.goruntule() // 20
- h.degerBelirle(20)
- h.goruntule() // 14
- o.degerBelirle(20)
- o.goruntule() // 24
- return 0
31SANAL YIKICI FONKSIYONLAR
- Problem Dinamik olarak yaratilmis nesneleri
delete operatörü ile yok etmek potansiyel bir
problem kaynagidir. Eger delete bir temel sinif
isaretçisine uygulaniyorsa, isaretçi türetilmis
bir sinifin nesne isaret ediyor bile olsa,
derleyici temel sinifin yikici fonksiyonunu
çagiracaktir. - Çözüm Bu sorun temel sinifin yikici fonksiyonunu
sanal yaparak çözülür. Bu seklide, türetilmis
siniflarin yikici fonksiyonlari da sanal yapilmis
olacaktir ve böylelikle delete operatörü temel
sinif isaretçisine uygulandiginda ilgili yikici
fonksiyon çagrilacaktir. - Ilke olarak sanal fonksiyon içeren bir sinif
yazildiginda, sanal bir yikici fonksiyon da
tanimlanmalidir. - Yikici fonksiyonlarin aksine, yapici fonksiyonlar
sanal olarak tanimlanamaz.