WwW.TaRaBuL.NeT
 

Kullanıcı ismi
Şifreniz

Konu Bilgileri
Konu Başlığı
C++[uyumluluk] 3
Konudaki Cevap Sayısı
0
Şuan Bu Konuyu Görüntüleyenler
 
Görüntülenme Sayısı
5

Yeni Konu aç  Cevapla
Alt 28.09.08, 14:24   #1 (permalink)
Kullanıcı Adı
Pc Kopat ADмiηistяαtOR™
Rütbesi
Yasal Uyarı
Cehennemden Çıkan Çılgın Türk
Üye Resmi
 
Baytar - ait Kullanıcı Resmi (Avatar)
Üye No
20
Bilgiler
Üyelik tarihi: Jul 2008
Mesajlar: 1.240
Konular: 1085
Online Süre: 5 gün 1 saat 2 dk
Reklam Komisyonu: 0
Cinsiyet
 Bay
Ruh HaLi
Nereden?
Dünyanın Merkezinden
İtibar
Tesekkür: 25
73 Mesajina 83 Tesekkür Aldi
Karizma
Rep Gücü : 8026
Rep Puanı : 800012
Rep Seviyesi : Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]Baytar Bilgelerin Üstadıdır [en son seviye]
Seviye: 30 [♥ Bé-Yêu ♥♥ Bé-Yêu ♥♥ Bé-Yêu ♥♥ Bé-Yêu ♥♥ Bé-Yêu ♥]
Aktiflik: 621 / 888
Güç: 413 / 1010
Deneyim: 60%
İletisim
Baytar - MSN üzeri Mesaj gönder
Standart C++[uyumluluk] 3

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 Bublic 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 Bublic 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ş
private

[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ş
private

[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ş
private

[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):
  • Üye fonksiyona ilişkin sınıf içerisinde,
  • Üye fonksiyonun taban sınıfları içerisinde,
  • Global faaliyet içerisinde aranır.

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:
  • İsim çözünürlük operatörüyle belirtilen sınıfta aranır.
  • Bulunamazsa çözünürlük operatörüyle belirtilen sınıfın taban sınıfınlarında aranır. Ancak global faaliyet alanında aranmaz.

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 Bublic 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!...
Baytar isimli Üye şimdilik offline konumundadır   Alıntı ile Cevapla
Konuyu Beğendin mi ? O Zaman Arkadaşınla Paylaş
Sayfayı E-Mail olarak gönder

Sponsorumuz
Yeni Konu aç  Cevapla

Bookmarks
Facebook Google Yahoo Live Digg Reddit del.icio.us StumbleUpon Bluedot Blinklist Netvouz Spurl Mister-Wong Furl

Tags
c++[uyumluluk]




internet kitapçınız kitapyurdu.com'dan binlerce kitaba ulaşabilirsiniz.



Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir)
 
Seçenekler
Stil

Yetkileriniz
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

Smileler Açık
[IMG] Kodları Açık
HTML-KodlarıKapalı
Trackbacks are Açık
Pingbacks are Açık
Refbacks are Açık

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

Bütün Zaman Ayarları WEZ +2 olarak düzenlenmiştir. Şu Anki Saat: 06:18 .
Powered by vBulletin Version 3.7.0 Beta 6
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.1.0 ©2007, Crawlability, Inc.
2oo8 © Copyright TaRaBuL.NeT(CoSKiM A.Ş. Kuruluşudur.)
Protected by CBACK.de CrackerTracker

17 18 19 20 21 22 24 25 26 27 34 35 36 38 39 40 45 46 47 48 49 50 51 52 53 54 55 58 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 78 79 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359