![]() |
||
|
|
#1 (permalink) |
|
nline Fonksiyonlar
C++’ta bir fonksiyon tanımlarken geri dönüş değerinin önüne inline anahtar sözcüğü getirilebilir. Örneğin: inline void fonk(void) { .... } (inline anahtar sözcüğü prototipte değil tanımlama sırasında kullanılmalıdır.) Bir inline fonksiyon tıpkı bir makro gibi işlem görür. Yani inline fonksiyon çağırıldığında fonksiyon çağırma kodu yerine fonksiyon kodunun kendisi yerleştirilir. /*-----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 yapılmak istenen makro ile yapılmak istenenle aynıdır. Makro ön işlemci tarafından açılırken inline fonksiyonlar derleme modülü tarafından açılmak. inline fonksiyonlar ile makrolar aynı amaçlar için kullanılmalarına karşın inline fonksiyonlar makrolara göre çok daha kullanışlı ve sağlamdır. Örneğin: Makrolar ++ ve – operatörleriyle çağırılamadığı halde(şüpheli kod oluşabilir), inline fonksiyonlar güvenli bir biçimde çağırılabilir. Çünkü inline fonksiyonlarda önce parametre ifadesi değerlendirilir, sonra açma işlemi gerçekleştirilir. Tabii inline fonksiyonlar normal bir fonksiyon gibi yazılıp çağırılırlar. Operatörlerin önceliğinden oluşacak problemler derleyici tarafından zaten giderilirler. inline fonksiyon parametrelerini parantez içerisine almaya gerek yoktur. inline fonksiyonlar diğer fonksiyonlarda olduğu gibi tür dönüştürmesi ve tür bakımından derleyicinin denetiminden geçerler. Yani inline fonksiyonlarda error’ler ortaya çıkabilir, böylece kod açılmadan hatalar tespit edilir. Yani daha sağlamdır. Bu nedenlerden dolayı C++’ta neredeyse makro hiç kulanılmaz. Hep inline fonksiyonlar kullanılır. Sınıfın normal türlerden veri elemanları da başlangıç fonksiyonunda “:” syntax’i ile ilk değer alabilirler. Örneğin: Eşdeğeri X::X(void):a(10), b(20) { .... } X::X(void) { a = 10; b = 20; } Örnek bir sınıf: CRect isimli sınıf MFC sınıf sistemi içerisinde kullanılan ve dörtgensel bölgeler üzerinde temel işleri yapmayı hedefleyen bir sınıftır. Sınıfın dörtgensel bölgeni sol üst ve sağ alt köşegenini belirleyen 4 veri elemanı vardır. /*-----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 { if(Width() && Height()) return 0; return 1; } void CRect: isp(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ş işte\n"); else printf("dolu\n"); } /*---------------------*/ Sınıfın Veri Elemanlarına Erişim ve “this” Göstericisi Bir sınıfın üye fonksiyonu bir sınıf nesnesiyle çağırıldığında aslında sınıf nesnesinin adresi gizlice üye fonksiyona geçirilir. Üye fonksiyon içerisinde sınıfın veri elemanlarına erişme bu gizlice geçirilmiş olan gösterici yluyla yapılır. Yani bir üye fonksiyonunun hiç parametresi yoksa aslında gizli bir parametresi vardır. Bu da çağırılan sınıf nesnesinin adresini tutan göstericidir. Sınıfın üye fonksiyonlarının, sınıfın veri elemanlarına erişmesi aslında adres yoluyla yapılmaktadır. Tabii kolaylık olması bakımından geçirilen bu gizli gösterici açıkça parametre listesinde görünmez. Erişim sırasında ok operatörü de kullanılmaz. C++’ta üye fonksiyonunu çağırılması C’deki karşılığı void Crect: isp(void) const{ printf(“[%d, %d; %d, %d]\n”, x1, y1, x2, y2); } void main(void) { CRect x(10, 10, 20, 20); x.Disp(); } void Crect_Disp(const Crect *this) { printf(“[%d, %d; %d, %d]\n”, this -> x1, this -> y1, this -> x2, this ->y2); } void main(void) { CRect x = {10, 10, 20, 20}; Crect_Disp(&x); } Üye fonksiyona gizlice geçirilen bu adres üye fonksiyon içerisinde açıkça “this” anahtar sözcüğüyle kullanılabilir. “this” parametre biçiminde programcı tarafından yazılamaz, ancak yazılmış gibi kullanılabilir. x bir sınıfın veri elemanı olmak üzere üye fonksiyon içerisinde x ile this -> x tamamen aynı anlamdadır. Bir üye fonksiyon başka bir üye fonksiyonu çağırıyorsa çağıran üye fonksiyona ilişkin this göstericisi doğrudan çağırılan fonksiyona geçirilir. “this” göstericisi global fonksiyonlarda kullanılmaz, sadece herhangi bir sınıfın üye fonksiyonu içerisinde kullanılabilir. “this” göstericisi hangi sınıfın üye fonksiyonunda kullanılırsa türü de o sınıf türünden gösterici olur. “this” gösterisinin değeri değiştirilemez. “this” göstericisi kendisi const olan const bir gösterici biçimindedir. /*-----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(); } /*-------------------*/ Sınıf İçi inline Fonksiyonlar Sınıfın veri elemanları private ya da protected bölüme yerleştirilmişse bu veri elemanlarına çeşitli public üye fonksiyonlarıyla erişilir. Bu tür fonksiyonlara “Get ve Set” fonksiyonları denir. Sınıfın bu tür küçük fonksiyonları tipik inline fonksiyonu olarak yazılmalıdır. Bir sınıfın üye fonksiyonunun tanımlanması dışarıda değil sınıfın içerisinde de yapılabilir. Örneğin: class X { int a, b; public: X(int x, int y) { 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 sınıf bildirimi içinde tanımlanan fonksiyonlar otomatik olarak inline fonksiyon olarak kabul edilir. Sınıf içerisinde tanımlanmış fonksiyonların sırasının hiçbir önemi yoktur. Yani yukarıdaki fonksiyon aşağıdaki fonksiyonu çağırabilir. “inline” bildirimi (dışarıda ya da gizlice sınıf içinde) bir zorunluluk biçiminde değil bir istek biçimindedir. Yani derleyici bir inline fonksiyonu inline olarak açamayabilir. Eğer açamazsa onu normal bir fonksiyon gibi ele alır. Açamadığından dolayı herhangi bir error ya da warning mesajı oluşmaz(tıpkı register anahtar sözcüğünde olduğu gibi). Genel olarak uzun kod içeren, karmaşık döngü ve if değimleri içeren fonksiyonlar inline olarak açılamazlar. Sınıfların Türetilmesi Daha önce yazılmış olan bir sınıfa ekleme yapılması istendiğinde başvurulacak en iyi yöntem türetme işlemidir. Bir sınıfa ek yapmak sınıfa yeni veri ve üye fonksiyonu eklemek anlamındadır. Bir sınıfa ek yapmak için türetme dışında birkaç yöntem akla gelebilir: 1. Sınıfa doğrudan ekleme yapmak Bu durumda önceki sınıfın bir kopyası çıkartılır ve üzerinde eklemeler yapılırsa, gereksiz bir biçimde üye fonksiyon tekrarı yapılır. 2. Önceki sınıfı bir veri elemanı olarak kullanan yeni bir sınıf tanımlamak class A { //... }; class B { A a; //... }; Bu durumda veri elemanı public bölgeye yerleştirilirse genişletilecek sınıfın üye fonksiyonları bu nesne sayesinde çağırılır. Ancak bu yöntem de türetme yöntemine göre çeşitli kısıtlamaları olan bir yöntemdir. Bir sınıfın işlevleri türetme yoluyla genişletilecekse türetmenin yapılavcağı sınıfa taban sınıf (base class), türetilmiş olan sınıfa da türemiş sınıf (derived class) denir. Şekilsel olarak türemiş sınıftan taban sınıfa bir ok olarak belirtilir. Türetme işleminin genel biçimi: [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image005.gif[/IMG] class <türemiş sınıf ismi>:[private/protected/public]<taban sınıf ismi> { } Örnek: class A { int a; //... }; class B ublic A {int b; //... }; İki nokta üstüste ayıracından sonra isteğe bağlı olarak türetme biçimi yazılabilir. Yazılmazsa private yazılmış gibi işlem görür. Türemiş sınıf türünden bir nesne tanımlandığında bu nesne hem taban sınıf veri elemanlarını hem de türemiş sınıf veri elemanlarını içerir. /*-----turetme.cpp-----*/ #include <stdio.h> class A { public: int a; }; class B ublic A {public: int b; }; void main(void) { B x; printf("%d\n", sizeof(x)); } /*------------------------*/ Türemiş Sınıf Nesnesinin Bellekteki Organizasyonu Türemiş sınıf nesnesinin taban sınıf veri elemanları ve türemiş sınıfın kendi veri elemanları blok olarak ardışıl bir biçimde yerleştirilir. Ancak taban sınıf ve türemiş sınıf veri elemanlarının hangisinin daha düşük adres bölgesine yerleştirileceği ANSI standartlarında belirlenmemiştir, dolayısıyla derleyiciyi yazanlara bırakılmıştır. A B B A Tabii derleyici organizasyonu hep aynı yapar. Yaygın kullanılan derleyicilerde taban sınıf veri elemanları düşük anlamlı adresi yerleştirilmektedir(Kursta bütün örneklerde önce taban sınıf veri elemanları düşük anlamlı adrese yerleştirilecektir). Türemiş Sınıflarda Erişim Kuralı Türemiş sınıflardaki erişim kuralı türetme biçimine bağlıdır. Public Türetmesi Public türetmesinde taban sınıfın public bölümü türemiş sınıfın public bölümüymüş gibi, taban sınıfın protected bölümü de türemiş sınıfın protected bölümüymüş gibi işlem görür. Taban sınıfın private bölümü erişime kapalıdır. Taban sınıfın private bölümüne türemiş sınıf tarafından erişilemez. Taban Türemiş [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image006.gif[/IMG]protected protected [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image007.gif[/IMG]public public Public Türetmesinden Çıkan Sonuçlar 1.Türemiş sınıf nesnesi yoluyla dışarıdan nokta ya da ok operatörü kullanılarak taban sınıfın public bölümüne erişilebilir. Ancak taban sınıfın protected ve private bölümüne erişilemez. 2.Türemiş sınıf üye fonkiyonları içerisinde taban sınıfın public ve protected bölümlerine doğrudan erişilebilir.ancak taban sınıfın private bölümüne erişilemez. Protected Türetmesi Bu türetme biçiminde taban sınıfın public ve protected bölümleri türemiş sınıfın protected bölümüymüş gibi işlem görür. Taban sınıfın private bölümü erişime kapalıdır. Türemiş sınıf tarafından erişilemez. Taban Türemiş [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image008.gif[/IMG][IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image009.gif[/IMG]protected protected public Protected Türetmesinden Çıkan Sonuçlar 1.Türemiş sınıf nesnesiyle dışarıdan nokta ya da ok operatörüyle taban sınıfın hiçbir bölümüne erişilemez. 2.Türemiş sınıf üye fonksiyonları içerisinde taban sınıfın public ve protected bölümlerine doğrudan erişilebilir. Ancak private bölümlerine erişilemez. Private Türetmesi Bu durumda taban sınıfın public ve protected bölümleri türemiş sınıfın private bölümüymüş gibi işlem görür. Taban sınıfın private bölümü erişime kapalıdır. Türemiş sınıf tarafından erişilemez. Taban Türemiş [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image010.gif[/IMG]protected private [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image011.gif[/IMG]public Private Türetmesinden Çıkan Sonuçlar 1.Türemiş sınıf nesnesi yoluyla dışarıdan nokta ya da ok operatörüyle taban sınıfın hiçbir bölümüne erişilemez. 2.Türemiş sınıf üye fonksiyonları içerisinde taban sınıfın public ve protected bölümlerine doğrudan erişilebilir. Ancak private bölümlerine erişilemez. Türetme İşleminden Çıkan Ortak Sonuçlar 1.Türemiş sınıf nesnesi yoluyla dışarıdan nokta veya ok operatörü kullanılarak ancak taban sınıfın public bölümüne ancak public türetmesiyle erişilebilir. Hiçbir zaman dışarıdan taban sınıfın protected ya da private bölümüne erişilemez. 2.Türemiş sınıf üye fonksiyonları içerisinde türetme biçimi ne olursa olsun taban sınıfın public ve protected bölümlerine erişilebilir. 3.Taban sınıfın private bölümü tam olarak korunmuştur. Türemiş sınıf tarafından doğrudan hiçbir şekilde erişilemez. En çok kullanılan türetme biçimi public türetmesidir. Protected Bölümünün Anlamı Protected bölüm dışarıdan doğrudan erişilemeyen, ancak türemiş sınıf üye fonksiyonları tarafından erişilebilen bir bölümdür. Protected bölümünün türetme dışında özel bir anlamı yoktur. Çünkü bu bölüm türemiş sınıfın çeşitli işlemlerini kolaylaştırmak için gereksinimlerini tutmakta kullanılır. Private Bölüme Fonksiyonları Yerleştirilmesi Bir sınıfın public bölümünde bulunan X() isimli fonksiyon işlemini gerçekleştirmek için işlemin belirli bölümlerini yapan, yani ara işlemleri yapan çeşitli fonksiyonlar kullanabilir. Bu ara işlemleri yapan fonksiyonların dışarıdan çağırılmasının hiçbir anlamı yoktur. Algıdan uzak tutmak amacıyla private bölüme yerleştirilebilirler. Sınıfı kullanacak kişi için private bölgenin incelenmesi gereksizdir. Somut, Soyut ve Arabirim Sınıflar Kendisinden başka bir sınıf türetilmeyecek biçimde tasarlanan sınıflara somut sınıflar (concreate cleass) denir. Somut sınıflar belirli bir konuda yararlı işlemleri yaparlar. Genellikle işlevlerinin genişletilmesi biçiminde bir istek söz konusu olmaz. Soyut sınıflar (abstract class) kendi başına bir anlamı olmayan kendisinden türetme yapılarak kullanılması zorunlu olan sınıflardır. C++’ta soyut sınıflar derleyici tarafından belirli bir syntax içimiyle doğrudan desteklenirler. Arabirim sınıflar (interface class) en çok rastlanan sınıflardır. Kendi başlarına yararlı işlemeleri yapabilen, ancak türetme işlemine de izin verebilecek biçimde tasarlanmış sınıflardır. Arabirim sınıfları tasarlayan kişi bunları türetme durumunu göz önüne alarak tasarlamalıdır. Türetme İşlemine Birkaç Örnek -Seri port işlemlerini yapan serial isimli bir sınıf olsun. Bu sınıfın üye fonksiyonları portu set etme, okuma ve yazma gibi temel işlemleri yapsın. Modem seri porta bağlanarak kullanılan, ve iletişimi sağlayan bir araçtır. Modemi programlamak için seri porta bilgi göndermek gerekir. Modem işlemlerini yapmak için serial sınıfından türetme uygulanabilir. Benzer biçimde laplink kablosu kullanarak seri portlar arası bilgi transferi için laplink isimli ayrı bir sınıf türetilebilir. -MFC sınıf sisteminde CWnd sınıfı genel olarak her türlü pencereyle ilgili işlem yapmak amacıyla kullanılır. Dialog pencereleri özel pencerelerdir. Yani bir pencerenin tüm özelliğini gösterir, ancak ek özelliklere de sahiptir. CDialog sınıfı CWnd sınıfından türetilmiştir. [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image012.gif[/IMG] Ancak her dialog penceresi kendine özgü farklılıklara sahiptir. MFC’de ne zaman bir dialog penceresi açılacak olsa CDialog sınıfından bir sınıf türetilmeli ve dialog penceresi o sınıfla ilişkilendirilmelidir. [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image013.gif[/IMG] Bu durumda MyDialog sınıfına ilişkin bir nesne tanımlanırsa bu nesne yoluyla CWnd sınıfına ilişkin üye fonksiyonlar çağırıldığında; pencereye ilişkin temel işlemler, CDialog sınıfının üye fonksiyonları çağırıldığında dialog pencerelerine ilişkin genel işlemler ve nihayet MyDialog sınıfına ilişkin üye fonksiyonlar çağırıldığında kendi dialog penceremizle ilgili özel işlemler yapılacaktır. Türemiş Sınıflarda Faaliyet Alanı Sınıf faaliyet alanı bir sınıfın ve ondan türemiş olan sınıfların üye fonksiyonları arasında tanınabilme aralığıdır. Bir veri elemanı ya da üye fonksiyonu aynı isimle taban ve türemiş sınıflarda tanımlı olabilir. Bu durumda: 1.Türemiş sınıf üye fonksiyonu içerisinde ilgili isim doğrudan kullanılırsa dar faaliyet alanına sahip olan yani türemiş sınıfta tanılanmış olan anlaşılır. Eğer istenirse çözünürlük operatörüyle sınıf ismi belirtilerek (X::a = 10) taban sınıftaki isme erişilebilir. 2.Türemiş sınıf nesnesi yoluyla dışarıdan nokta ya da ok operatörüyle aynı isimli değişkene ya da fonksiyona erişildiğinde yine dar faaliyet alanına sahip olan türemiş sınıftaki isim anlaşılır. Ancak nokta ya da ok operatöründen sonra yine çözünürlük operatörü kullanılabilir (p->X::a). 3.Taban ve türemiş sınıf içerisinde aynı isimli fakat farklı parametre yapılarına sahip fonksiyonlar olsun. Eğer türemiş sınıfın başka birt üye fonksiyonunda aynı isimli fonksiyon çağırılmışsa bu fonksiyon yalnızca dar faaliyet alanında aranır. Yani parametre yapıları farklı bile olsa dar faaliyet alanındaki diğerini gizlemektedir. Aynı durum dışarıdan türemiş sınıf nesnesi yoluyla nokta ya da ok operatörüyle de söz konusu olur. Yani dar faaliyet alanındaki isim geniş faaliyet alanını gizleyerek bu ismin orada aranmamasını sağlar(Global fonksiyon çağırırken :: operatörü fonksiyon isminin önüne getirilir). Bir sınıfın üye fonksiyonu içerisinde bir fonksiyon çağırımış olsun. Derleyici bu ismi sırasıyla şuralarda arar(name lookup):
Bir üye fonksiyon içerisinde fonksiyon ismi, sınıf ismi ve çözünürlük operatörüyle çağırılmışsa isim sırasıyla şuralarda aranır:
Eğer unary çözünürlük operatörü ile çağırılmışsa (::fonk(); ) isim yalnızca global faaliyet alanında aranır. Bir sınıfın üye fonksiyonu içerisinde sınıfın ve taban sınıfların global fonksiyonla aynı isimli fonksiyonları olmasa bile çağırma işlemi okunabilirlik bakımından yine unary çözünürlük operatörü kullanılarak yapılmalıdır. Fonksiyonlar için belirtilen bu arama durumlarının hepsi normal değişkenler için de geçerlidir. Türemiş Sınıfın Taban Sınıfı Çağırması İşlemleri 1FC0 Normal olarak türemiş sınıf taban sınıfa erişebilir. Yani türemiş sınıf nesnesiyle ya da türemiş sınıf üye fonksiyonları içerisinde taban sınıf nesnesi ya da fonksiyonları kullanılabilir. ancak tersi durum mümkün değildir. Yani taban sınıf türemiş sınıfa erişemez. Taban sınıf derlenirken derleyici bundan bir sınıf türetileceğini bilmek zorunda değildir. Bu durumda türemiş sınıf nesnesi ile taban sınıf üye fonksiyonu çağırıldığında derleyici bu fonksiyona this göstericisi olarak türemiş sınıf nesnesinin taban kısmının adrsini geçirir. Uygulamada taban sınıf veri elemanları daha düşük adrese yerleştirildiğinden geçirilen adres nesnenin bütünsel başlangıç adresiyle aynı olur. [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image014.gif[/IMG] 1FC2 [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image015.gif[/IMG] B B x; x.fonka(); Burada A taban sınıfının fonka üye fonksiyonuna this göstericisiyle 1FC0 adresi geçirilmektedir. Türemiş sınıf nesnesiyle türemiş sınıfın üye fonksiyonu çağırıldığında yine taban sınıf veri elemanlarının bulunduğu toplam veri adresi geçirilir. Çünkü türemiş sınıf üye fonksiyonu içerisinde taban sınıf üye fonksiyonu çağırıldığında derleyici taban sınıf veri bloğunun adresini tespit edebilmek zorundadır. Bir Dizi Türetme Yapılması Durumu Tüeretme işlemi birden fazla yapılabilir Bu durumda yukarıdaki sınıflar aynı kurallarla aşşağıdan erişilebilir. Bir sınıfın bir dizi türetme yapıldığında bir üsteki taban sınıfına doğrudan tan sınıf (direct base class) sonraki taban sınıflarına ise dolaylı taban sınıf (indirect base class) denir. Bir sınıf birden fazla sınofa taban sınıf olabilir. Bu durum çatışmaya yol açmayacak biçimde açık ve anlaşılır bir türetme durumudur. A [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image016.gif[/IMG][IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image017.gif[/IMG] B C [IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image018.gif[/IMG][IMG]file:///C:/DOCUME%7E1/naim/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image019.gif[/IMG]Ancak bir sınıffın birden fazla taban sınıfa sahip olması ayrı bir bölümde incelenecek kadar karmaşık bir konudur. Bu duruma çoklu türetme denir. Çoklu türetme diğer bilgisayar dillerinde desteklenmemektedir. A B C Taban Sınıf Türünden Göstericilere Türemiş Sınıf Nesnelerinin Adreslerinin Atanması C++'ta bir göstericiye farklı türden bir göstericinin atanması uyarı değil error gerektirir. Ancak istisna olarak taban sınıf türünden bir göstericiye türemiş sınıf türünden bir nesnenin adresi atanabilir. Ancak bunun tersi olan durum, yani türemiş sınıf türünden bir göstericiye taban sınıf türünden bir nesnenin adresinin atanması durumu yararlı ve geçerli bir işlem değildir. class A { .. .. }; class B ublic A {.. .. }; void main(void) { A *p; /*Taban sınıf türünden bir gösterici*/ B x; /*Türemiş sınıf türünden nesne*/ A y; /*Taban sınıf türünden bir nesne*/ B *t; /*Türemiş sınıf türünden bir gösterici*/ p = &x; /*Geçerli*/ t = &y; /*Geçersiz*/ } Türemiş sınıf nesnesi taban sınıf veri elemanlarını içerdiğine göre türemiş sınıf nesnesinin adresi taban sınıf göstericisine geçirildiğinde problemli ya da güvensiz bir durum oluşmaz. Derleyici bu durumda türemiş sınıf nesnesinin taban sınıf veri elemalarının adresini göstericiye atar. Taban sınıf göstericisiyle ancak taban sınıf üye fonksiyonları çağırılabileceğine göre bu göstericiyle tahsis edilmiş bir alana erişilir, yani uygunsuz bir durum oluşmaz. Mademki taban sınıf ve türemiş sınıf veri elemanlarının yerleşimi kesin bir standartla belirlenmemiştir, böyle bir atamada derleyici türemiş sınıf nesnesinin taban sınıf elemanlarının başlangıç adresini tespit edip o adresi atamalıdır. Tabii genellikle taban sınıf veri elemanları düşük anlamlı adrese yerleştirildiğinden geçirilen adres de nesnenin bütününün başlangıç 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; } }; 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: ispA(void){ printf("%d\n", a); } void B: ispB(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 türemiş sınıflardır: { B *p; C n; p = &n; /*Geçerlidir, p'ye A'nın başlangıç adresi, geçirilir*/ } Türemiş Sınıf Nesnesinin Adresinin Taban Sınıf Göstericisine Atanması İşleminin Program İçerisinde Karşılaşılabilen Çeşitli Durumları Türemiş sınıf nesnesinin adresi açık ya da gizli çeşitli kodlarla taban sınıf göstericisine geçirilebilmektedir. 1. Açık bir biçimde yapılan atamalarla: Yani taban sınıf türünden bir gösterici tanımlanır, türemiş sınıf türünden bir nesnenin adresi atanır. { A *p; /*Taban sınıf türünden bir gösterici*/ B x; /*Türemiş sınıf türünden nesne*/ p = &x; /*Geçerli*/ } --------------------------------------------------------------------------------------------------------- Altın harflerle yaz mahlasımı. halvetim kasvet, kem gözlere şiş!... Cadü ya herru!...ya merru!...kafkef, gölge harâmilerine bir selam çak!... Abile ğatladı, demlenir simam, nüşinrevan'dan handan ummam ben. Ahu-yi felek mum, ben şamdan. düşmez kalkmaz bir Allah'tır uyan!... |
|
|
|
|
| Sayfayı E-Mail olarak gönder |
| Sponsorumuz |
![]() |
| Bookmarks | |||||||||||||
Facebook
|
Google
|
Yahoo
|
Live
|
Digg
|
Reddit
|
del.icio.us
|
StumbleUpon
|
Bluedot
|
Blinklist
|
Netvouz
|
Spurl
|
Mister-Wong
|
Furl
|
| Tags |
| c++[uyumluluk] |
| Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir) | |
| Seçenekler | |
| Stil | |
|
|
Benzer Konular
|
||||
| Konu | Konuyu Başlatan | Forum | Cevaplar | Son Mesaj |
| C++[uyumluluk] 2 | Baytar | Bilgisayar Programlama | 0 | 28.09.08 14:24 |
| C++[uyumluluk] 1 | Baytar | Bilgisayar Programlama | 0 | 28.09.08 14:23 |