ArenaFutbol | Futbol'a Dair Her Şey
c++ da operatörler Uyeol

Sitemizi REKLAMSIZ şekilde gezebilmek için, bütün bölümlere erişebilmek için ve tam anlamıyla faydalanabilmek için lütfen ÜYE OLUNUZ, eğer üye iseniz lütfen GİRİŞ YAPINIZ
ArenaFutbol | Futbol'a Dair Her Şey
c++ da operatörler Uyeol

Sitemizi REKLAMSIZ şekilde gezebilmek için, bütün bölümlere erişebilmek için ve tam anlamıyla faydalanabilmek için lütfen ÜYE OLUNUZ, eğer üye iseniz lütfen GİRİŞ YAPINIZ
ArenaFutbol | Futbol'a Dair Her Şey
Would you like to react to this message? Create an account in a few clicks or log in to continue.



 
AnasayfaGaleriLatest imagesKayıt OlGiriş yap

 

 c++ da operatörler

Aşağa gitmek 
YazarMesaj
Rebellious
No-Post !
Rebellious


Favori Oyuncu : Metin Oktay
Mesaj Sayısı : 14623
Puan : 258186
Rep : 2564
Yer : Ali Samiyen
Cinsiyet : Erkek
Kayıt tarihi : 19/08/09
c++ da operatörler I231076_gsli

c++ da operatörler Empty
MesajKonu: c++ da operatörler   c++ da operatörler EmptyPtsi Haz. 14, 2010 1:12 am

DEĞİŞKENLER VE SABİTLER

Temel Veri Tiplerinin Uzunlukları
Not : Bu değerler 32 bit uygulama geliştirme ortamındaki platformlara
özeldir. Platformdan platforma değişebilir.
Bool : 0--1 long
: -2,147,483,648—2,147,483,647
Char : -128—127 float
: 3.4E+/-38
Enum : int ile aynı değerde double :
1.7E+/-308
İnt : -2,147,483,648—2,147,483,647 long double :
1.2E+/-4932



Temel Veri Tipleri : bool true ve false değerlerini alır. true = 1,
false = 0 gibi düşünelebilir. Derleyicisine göre Bool şeklindede
tanimlanıyor olabilir.

char ASCII karakterleri ve çok küçük sayılar için kullanılır.
enum Sıralanmış değerleri tutar.
int Sayma sayıları.
long Sayma sayıları.
float Ondalıklı sayılar.
double Ondalıklı sayılar.
long double Ondalıklı sayılar.
void Değersiz - boş.


unsigned : Belli veri tiplerinin işaretsiz değerler almasını sağlar.

Örneğin;
unsigned char 0 – 255 arasında değer alır.
Dikkat edilecek olunursa negatif kısım atılmış ve burada ki değer
uzunluğu pozitif kısıma eklenmiş.
unsigned char; int ve long türlerine uygulanabilir.

typdef - Türleri kendinize göre adlandırın :

typdef kullanarak tanımlanmış türleri kendinize göre
adlandırabilirsiniz.
Dikkat ediniz ki bu şekilde yeni bir tür yaratmıyorsunuz. Ayrıca bu
isimlendirmenizi diğer tiplerle birlikte kullanamazsınız.

Örneğin:

typdef double FINANSAL artık double yerine FINANSAL kullanabilirsiniz.
long FINANSAL şeklinde bir kullanım hatalıdır.


5.1 Sabit Tanımlama

C dilinde kullanılan define yerine C++’ta const ile sabitler
tanımlanabilir.

const int max=100; // Program içinde değiştirilemez

Const ile tanımlanan sabitler herhangi bir tipten (önceden tanımlanmış
ya da kullanıcı tipi) olabilir. Herhangi bir değişken gibi const ile
tanımlı sabitler de scope alanına sahiptir).


5.2 Değişkenler

Değişken Nedir?
Değişken belli bit türe ait verileri saklayan veri deposudur. Aksi
belirtilmedikçe içerikleri değiştirilebilir.

5.2.1 Değişkenlerin İsimlendirilmesi:

Değişken isimlendirilmesi konusunda programcı tutarlı bir yöntem
izlemelidir. Örneğin Windows ortamında macar notasyonu denilen
isimlendirme tekniği yoğun olarak kullanılmaktadır. Macar notasyonu
C++’a özgü bir isimlendirme tekniği değildir. C ve yapısal programlama
dilleri için düşünülmüştür. İster macar notasyonu kullanılsın ister
başka bir notasyon kullanılsın C++ için şu konularda tutarlılık
sağlanmalıdır:

- Sınıf isimleri her sözcüğün ilk harfi büyük olacak şekilde ya da
tutarlı başka bir yöntemle belirlenmelidir. C++’da yapılarda bir sınıf
olduğu için yapılarla sınıflar aynı biçimde isimlendirilebilir.
Yapıların tamamen C’deki gibi kullanıldığı durumlarda yapı isimleri her
harfi büyük olacak biçimde belirlenebilir. Bazı kütüphanelerde sınıf
isimlerinin başına özel bir karakter de konulabilmektedir. Örneğin
MFC’de sınıf isimlerinin başına ‘C’ getirilmektedir (CWnd, CBrush,
CObject gibi ...).
- Sınıfın veri elemanları üye fonksiyonlar içerisinde kolay teşhis
edilsin diye ayrı bir biçimde isimlendirilmelidir. Genellikle veri
elemanları, başına ya da sonuna ‘_’ konularak ya da ‘d_’, ‘m_’ gibi
önekler ile başlatılır.
- Global değişkenler de özel bir biçimde isimlendirilmelidir. Pek çok
programcı global değişkenleri ‘g_’ öneki ile başlatarak
isimlendirmektedir.
- Üye fonksiyonlar içerisinde global fonksiyonlar çağırılırken vurgulama
için unary :: operatörü kullanılmalıdır. Örneğin:

::SetData(100);

5.2.2 Değişken isimlerini tanımlarken dikkate alınacak noktalar :
C++ dilinde de C dilinde ki gibi büyük ve küçük harfler farklı
verileri temsil eder.

Örneğin;
char c;
char C;
int sayi;
int Sayi;
c ve C hafızada farklı yerleri gösterirler. sayi ve Sayi' da farklıdır.

Değişkenler harflerle ya da _ başlar.
İçlerinde boşluk yoktur.

Değişkenler istenildekleri yerde tanımlanabilirler. Ancak burada
dikkate alınması gereken noktalar vardır. Lütfen bölüm sonundaki
örneklere göz atınız.

5.2.3 Değişkenlere değer atanması :
Bir değişkene değer atamak için = operatörü kullanılır. Değişkene değer
atama tanımlandığı zaman yapılabildiği gibi daha sonradanda yapılabilir.


Örneğin;
Tanımlama sırasında değer atama:
char c = 'c';
int sayi = 100;
Daha sonradan değer atama:
char c;
int sayi;
c = 'c ';
sayi = 100;

Aynı anda birden fazla değişken tanımlanabilir, ve aynı anda birden
fazla değişkene değer atanabilir;

int i , j , k;
i = j = k = 100;
i,j,k'nın değeri 100 oldu.


5.3 Programlara Açıklama Eklenmesi

Açıklama Nedir?

Değişkenleri tanımlarken dikkat ettiyseniz her C++ komutu ; (noktalı
virgül) ile bitiyor. Bu derleyiciye komut yazımının bittiğini belirtmek
için kullanılıyor. Programlar uzadıkça ve karmaşıklaştıkça programımıza
bir daha ki bakışımızda neyi neden yaptığımızı unutabiliriz. Ya da
yazılmış olan programı bizden başka kişilerde kullanacak olabilir.
Bundan dolayı ne yaptığımıza dair açıklamaları kodun içine
serpiştirmeliyiz. Yazdığınız komutlar basit fonksiyonları içerse de
detaylı şekilde açıklama eklemenizi öneririm. Böylecene aylar sonra
kodunuza tekrar baktığınızda ne yaptığınızı kolayca hatırlayabilirsiniz.


Açıklamaları C++'ta nasıl tanımlayacaksınız?
C++ program içerisine iki şekilde açıklama eklemenize izin veriyor.
Biri C' nin açıklama ekleme şekli olan // kullanılması. C++ derleyicisi
// 'den sonra satır boyunca yazılanların tümünü yok sayar.

Örneğin:
// Bu satır derleyici tarafından umursanmaz
// Ve ben satırın başına // yazarak bu satırın açıklama olduğunu
belirtiyorum
// Aşağıda da örnek bir değişken tanımlanmıştır.
long örnek;

C++’ ın C 'den farklı olarak birden fazla satıra açıklama yazmayı
sağlayan bir yapı daha vardır. Bu yapı /* ile başlar */ ile biter.
Yukarıdaki örneği bu yapı ile aşağıdaki gibi tanımla yabiliriz.

/* Bu satır derleyici tarafından umursanmaz
Ve ben satırın başına // yazarak bu satırın açıklama olduğunu
belirtiyorum
Aşağıda da örnek bir değişken tanımlanmıştır.*/
long örnek;


6 OPERATÖRLER

6.1 NEW OPERATÖRÜ

Genel biçimi:

new <tür> [<[uzunluk]>]

new int
new char
new double [10]
new float[n]
new char[strlen(s) + 1]

Eğer köşeli parantez olmadan sadece tür ismi isle tahsisat yapılırsa
o türden bir elemanlık yer tahsis edilmiş olur. Örneğin: new int à1
int'lik yer tahsis edilmiştir.
Eğer köşeli parantez içerisine ifade yazılarak kullanılırsa bu
durumda o ifade ile belirti- len sayıda elemanlık alan tahsis edilir.
New operatörü türü belirli bir alan tahsis eder. Yani new operatörüyle
elde edilen adresin tür bileşeni çağırılma ifadesindeki tür ile aynı
olur.

int *p;
p = new int; /* Burada sizeof(int) kadar byte tahsis ediliyor ve
tahsis edilen */ /* alanın başlangıç adresi elde ediliyor.
Bu adres int türündedndir. */
char *p;
p = new int [10]; /* C++'ta hatadır. */
p = (char *)new int[10]; /* Hata değil. */

/*----------new1.cpp---------*/
#include <stdio.h>
#include <string.h>

void main(void)
{
char *p;

p = new char[30];
gets(p);
puts(p);
}
/*------------------------------*/

New bir operatördür. Ancak derleyici bu operatör kullanıldığında
dinamik tahsisat işleminin yapılmasını sağlamak için dinamik tahsisat
yapan bir fonksiyonun çağırma kodunu amaç koda ekler. Yani new bir
operatör olmasına karşın tahsisat işlemi yerleştirilen bu fonksiyon
sayesin de programın çalışma zamanı sırasında yapılmaktadır. Bu operatör
öncelik tablosunun ikinci düzeyinde bulunmaktadır.
Örneğin:
new int + n
gibi bir işlem geçerlidir. İşlemler:
İşlem 1 : new int
İşlem 2 : İşlem 1 + n

new operatörü tahsisat işlemini yapamazsa 0 değerini(NULL gösterici)
üretir.

/*-------freestor.cpp------*/
/*free store alanının hesaplanması*/
#include <stdio.h>

#define BLOCKSIZE 1024

void main(void)
{
long size = 0;
char *p;

for(;Wink{
p = new char[BLOCKSIZE];
if(p == NULL)
break;
size += BLOCKSIZE;
}
printf("Free store size = %ld\n", size);
}
/*---------------------------*/

Köşeli parantez içerisine yazılan ifade sabit ifadesi olmak zorunda
değildir.

/*-----------new2.cpp---------*/
/*Tam olarak ad sosay uzunluğu kadar bellek tahsis eden fonksiyonun
kullanılışı*/
#include <stdio.h>
#include <stdlib.h>

char *getname(void)
{
char *p;
char buf[80];

printf("Adı Soyadıc++ da operatörler Smile;
gets(buf);
p = new char[strlen(buf) + 1)];
if(p == NULL){
printf("Cannot allocate memory..\n");
exit(1);
}
strcpy(p, buf);
return p;
}

void main(void)
{
char *p;

p = getname();
puts(p);
}
/*--------------------------------*/
6.2 DELETE OPERATÖRÜ

Delete operatöürü new operatörüyle tahsis edilmiş olan blokları serbest
bırakmak için kulla nılır.
Genel biçimi:
1. delete p;
2. delete [] p;

Eğer tahsisat tek parça olarak yapılmışsa yani köşeli parantez
kullanılmadan yapılmışsa sil me işlemi köşeli parantez kullanılmadan
yapılmalıdır.
Örneğin:

int *p;
p = new int;
delete p;

Eğer tahsisat işlemi birden fazla eleman için yapılmışsa yani köşeli
parantez kullanılarak yapılmışsa serbest bırakma işleminde de köşeli
parantez kullanılmalıdır.
Örneğin:

int *p;
p = new int[n];
delete [] p;

Burada köşeli parantez içerisine bir şey yazılmaz. delete operatörü
unary prefix bir operatördür ve öncelik tablosunun ikinci düzeyinde
bulunur.

delete p + 1; /*Hatalı*/
delete (p + 1);/*Doğru*/


delete operatörünün operandı daha önce tahsis edilmiş olan bloğun
başlangıç adresi olmalıdır. Değilse beklenmeyen sonuçlar ortaya
çıkabilir. Tabii derleici delete operatörüne karşılık amaç koda (object
module'e) free gibi tahsis edilmiş bloğu serbest bırakan bir fonksiyon
kodu yerleştirmektedir. new delete operatörlerinin tahsisat işlemlerinde
kullandığı fonksiyon maloc, calloc, free fonksiyonları olmak zorunda
değildir. Bu iki grup fonksiyon farklı tahsisat tabloları kullanıyor
olabilir. Bu nedenle new delete operatörleriyle malloc, calloc, free
gibi standart C fonksiyonlarını özel bir durum yoksa birlikte
kullanmamak gerekir. Çünkü bir grup tarafından tahsis edilen alan diğer
grup tarafından tahsis edilmemiş gibi gözükebilir. Görüldüğü gibi C++'ta
realloc fonksiyonun karşılığı bir operatör yoktur. Ancak böyle bir
fonksiyon yazılabilir.
/*------------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;
}
/*----------------------------------------*/


Kullanımı:
p = new char [10]; /* 10 * sizeof(char) kadar bellek tahsis
edildi */
p = Realloc(p, 20, 10); /* Tahsis edilmiş alan 20 * sizeof(char)'e
büyütüldü */

6.3 REFERANS OPERATÖRÜ &

& operatörü bir değişkenin adresini verir.

int i;
int &j=i; // j ile i aynı adrese sahip
i=5;
j++; // i=6 oldu

Fonksiyonlara değişken parametre aktarımında kullanılır. Bunun için C’
de kullanılan işaretçi ile aktarım yöntemi programın okunuşunu
zorlaştırmaktadır.

void hesap(int j) {j=j*j/2;} // j değişmez, fonksiyon anlamsız
void main()
{
int i=5;
hesap(i); // i değişmez
}

İşaretçi (pointer ) kullanarak çözüm
void hesap(int *j) {
*j=*j**j/2;
}
void main()
{
int i=5;
hesap(&i);
}

C++’ta referans kullanarak çözüm
void hesap(int &j){ j=j*j/2;}
void main()
{
int i=5;
hesap(i);
}
Burada fonksiyonun parametreyi değişken olarak aldığı kullanıcı programa
saydamdır.


6.4 DEĞİŞKEN TANIMLAMA YERLERİ VE "SCOPE" OPERATÖRÜ ::

Değişkenler gerekli oldukları yerlerde tanımlanabilirler. Bu özellik
programın anlaşılırlığını artırır.
int a=0;
for (int i=0; i < 100; i++){ // kullanıldığı yerde tanımlama
a++;
...

int p=12;
... // p’nin kullanım yeri
}
int p=1; // farklı bir p
} // buradan sonra i tanımsız

! : For döngüsünden önce tanımlanan i değişkeni, tanımlandığı satırdan,
for döngüsünü kapsayan bloğun sonuna kadar tanımlı kalır.

Scope operatörü :: ile örtülmüş global değişkenlere erişilebilir.
int x=1;
void f(){
int x=2; // Yerel x
:Mad++; // Dışarıdaki x
}

6.5 Yeni Tür Dönüştürme Operatörleri
Bilindiği gibi C++'da C'de kullanılan klasik tür dönüştürme operatörü
aynı şekilde kullanılmaktadır. Yine ayrıca tür dönüştürme operatörünün
fonksiyonel biçimi denilen biçimi de C++'a özgü olarak kullanılır.
Örneğin:

(int) a; //Normal biçim
int (a); //Fonksiyonel biçim

Ancak bunların dışında tamamen konulara ayrılarak uzmanlaştırılmış özel
tür dönüştürme operatörleri de vardır. C++'ın yeni tür dönüştürme
operatörleri şunlardır:

1-static_cast
2-const_cast
3-reinterpret_cast
4-dynamic_cast

Bu operatörlerin kullanım syntaxı şöyledir:

operator_ismi<dönüştürülecek tür>(dönüştürülecek ifade)

Örneğin:
a = static_cast<int>(b);

Aslında normal tür dönüştürme operatörü bunların hepsinin yerini tutar.
Yeni operatörler belirli konularda uzmanlaştığı için daha güvenli kabul
edilmektedir.

6.5.1 STATİC_CAST OPERATÖRÜ

Bu operatör standart dönüştürmelerde kullanılır, yani:

1- C'nin normal türleri arasında yapılan dönüştürmelerde. Örneğin:

long b;
int a;
a = static_cast<int>(b);

2- Türemiş sınıf türünden adresin taban sınıf göstericisine
dönüştürülmesi durumunda. Örneğin:

A *pA;
B b;
pA = static_cast<A *>(&b);

3- Taban sınıf türünden adresin türemiş sınıf türüne dönüştürülmesi
durumunda. Örneğin:

A *pA;
B b;
B *pB;
pA = static_cast<A *>(&b);
pB = static_cast<B *>(pA);


6.5.2 CONST_CAST OPERATÖRÜ

Bu operatör const ve/veya volatile özelliklerini bir göstericiden
kaldırmak için kullanılır, yani örneğin const int * türünü int * türüne
dönüştürmek için bu operatör kullanılmalıdır.

Örnek:

const int x;
int *p;

p = const_cast<int *>(&x);

Bu operatör const/volatile özelliğini kaldırarak başka bir türe
dönüştürme yapamaz. Örneğin:

int *pi;
const char *pcc;

pi = const_cast<int *>(pcc); //error

Görüldüğü gibi bu operatörde dönüştürülecek tür dönüştürülecek ifade ile
aynı türden olmalıdır. Bu operatörle gerekmese bile const olmayan
adresten const adrese dönüştürme yapılabilir.


6.5.3 REİNTERPRET_CAST OPERATÖRÜ

Bu operatör bir adresi başka türden bir adrese dönüştürmek için ve
adreslerle adres olmayan türler arasındaki dönüştürmeler için
kullanılır. Örneğin:

int *pi;
char *pc;
...
pc = reinterpret_cast<char *>(pi);
pi = reinterpret_cast<int *>(pc);

Bu operatör const/volatile özelliklerini kaldırmaz. Bu operatörle taban
sınıf türemiş sınıf arasında da dönüştürme yapılabilir. Ancak bu
operatör const bir adresten başka türün const olmayan bir adresine
dönüşüm yapmaz. Bu işlem aşağıdaki gibi iki aşamada yapılabilir:

const char *pcc;
int *pi;
...
pi = reinterpret_cast<int *>(const_cast<char *>(pcc));


6.5.4 RTTI ÖZELLİĞİ, TYPEİD VE DYNAMİC_CAST OPERATÖRLERİ

RTTI (Run Time Type Information) özelliği aslında temel olarak
çokbiçimlilik konusunda bir göstericinin ya da referansın gerçekte hangi
türemiş sınıfı gösterdiğini tespit etmek için düşünülmüştür. Örneğin
bazen türemiş sınıfın adresi bir taban sınıf göstericisine atanır sonra
yeniden orijinal türe dönüştürülmek istenir. Ancak programcı çeşirli
nedenlerden dolayı orijinal türü tespit edemiyor olabilir. Bir türetme
şeması olsun en tepedeki taban sınıfın A sınıfı olduğunu varsayalım. A
sınıfı türünden pA isimli bir gösterici tanımlamış olalım, programın
çalışma zamanı sırasında pA'ya herhangi bir türemiş sınıf nesnesinin
adresi atanmış olsun. Biz bunu bilmiyorsak çalışma zamanı sırasında
tespit edebilir miyiz? İşte RTTI konusunun ana noktasını bu
oluşturmaktadır. RTTI mekanizması derleyiciye pekçok yük getirdiği için
ve çalışabilen kodun verimini düşürebildiği için derleyicilerin
pekçoğunda bu özellik isteğe bağlı bir biçimde yüklenebilmektedir. RTTI
özelliği VC++ derleyicisinde Project/Settings/C-C++/C++ Language/RTTI
kısmından ayarlanabilir ve bu özellik default olarak kapalıdır.

RTTI özelliği için type_info isimli bir sınıf kullanılır. Bu sınıf
<typeinfo> dosyasında bildirilmiştir.

class type_info {
public:
virtual ~type_info();
bool operator==(const type_info &rhs) const;
bool operator!=(const type_info &rhs) const;
bool before(const type_info &rhs) const;
const char *name() const;
};

type_info sınıfı da diğer sınıflarda olduğu gibi std namespace'i
içerisinde bildirilmiştir. Sınıfın == ve != operatör fonksiyonu tamamen
iki sınıfın aynı türden olup olmadığını kontrol etmek için kullanılır.
name() üye fonksiyonu ilgili türün ismini elde etmekte kullanılır.
before() fonk siyonu ilgili çokbiçimli sınıfın türetme ağacında daha
yukarıda olup olmadığı bilgisini elde etmekte kullanılır.

6.5.5TYPEİD OPERATÖRÜ

typeid RTTI konusunda kullanılan bir operatördür. Kullanımı şöyledir:

typeid(ifade)

Bu operatör ifadenin türünü tespit eder ve ifadenin türüne uygun const
type_info & türünden bir değer üretir. Burada belirtilen ifade
herhangi bir tür ismi olabilir (sizeof operatöründe olduğu gibi) ya da
normal bir ifade olabilir. İfade çokbiçimli bir sınıf içerisinde bir
nesne belirtiyorsa elde edilecek bilgi çalışma zamanı sırasındaki gerçek
sınıfa ilişkindir. Örneğin p çokbiçimli bir türetme şeması içerisinde
bir gösterici olsun *p typeid operatörüne operand yapılırsa p'nin
gösterdiği gerçek sınıfın tür bilgisi elde edilir. Yani B sınıfı A
sınıfından türetilmiş olsun aşağıdaki örnekte B sınıfının bilgileri elde
edilecektir:

A *pA = new B();

typeid(*pA) //Burada B ile ilgili bilgiler elde edilir

Ancak derleyiciler bu bilgileri sanal fonksiyon tablolarından elde
ettiği için sınıf sisteminin bir çokbiçimlilik özelliğine sahip olması
gerekir. Bunu yapmak için en pratik yöntem en taban sınıfa bir sanal
bitiş fonksiyonu eklemektir. type_info sınıfının atama operatör
fonksiyonları ve başlangıç fonksiyonları sınıfın private bölümüne
yerleştirilmiştir, bu yüzden type_info sınıfı türünden bir nesne
tanımlanamaz ve typeid operatörünün ürettiği değer başka bir sınıf
nesnesine atanamaz. Bu değer doğrudan aşağıdaki gibi kullanılmalıdır:

cout << typeid(int).name() << "\n";

typeid operatörüyle derleyicinin yaptığı işlemleri şöyle
özetleyebiliriz:

1- Eğer RTTI özelliği etkin hale getirilmişse derleyici bütün çokbiçimli
olmayan sınıflar için ve C++'ın doğal türleri için statik düzeyde bir
tane type_info sınıfı tahsis eder ve typeid operatörü doğrudan bu sınıf
ile geri döner.

2- Eğer çokbiçimli bir sınıf sistemi sözkonusuysa derleyici type_info
sınıf bilgilerini sınıfların sanal fonksiyon tablolarında tutar böylece p
bu sınıf sisteminde bir adres olmak üzere typeid(*p) ifadesi ile p
göstericisinin ilişkin olduğu sınıfa ilişkin bilgi değil, onun gerçekte
gösterdiği sınıfa ilişkin bilgi elde edilmektedir. Burada önemli bir
nokta eğer sınıf sistemi çokbiçimli değilse typeid(*p) ile p'nin
gösterdiği yerdeki gerçek sınıfa ilişkin değil p'nin türüne ilişkin
değer elde edilir. Örnek:

#include <iostream>

class A {
public:
virtual ~A() {}
};

class B : public A{
public:
virtual ~B() {}
};

using namespace std;

void main()
{
A *pA = new B();

cout << typeid(*pA).name() << endl; // class B yazar
}

type_info sınıfının == ve != operatör fonksiyonları aslında sınıfların
isimlerine bakarak bir karşılaştırma yapar. Biz bu operatör
fonksiyonlarını çokbiçimli bir yapı içerisinde bir göstericinin
içerisindeki adresin gerçekte belirli bir sınıfı gösterip göstermediğini
anlamak için kullanırız. Örneğin pA A sınıfı türünden bir gösterici
olsun, şimdi biz pA'nın gerçekte B sınıfını gösterip göstermediğini
aşağıdaki gibi anlayabiliriz:

if (typeid(*pA) == typeid(B)) {
//...
}

Türetme şemasında aşağıdan yukarıya doğru yapılan dönüştürmeler (upcast)
normal dönüştürmelerdir. Hâlbuki yukarıdan aşağıya yapılan
dönüştürmeler (downcast) eğer haklı bir gerekçe yoksa güvensiz bir
dönüştürmedir. Örneğin türemiş sınıf nesnesinin adresi taban sınıf
göstericisine atanabilir ve sonra yeniden türemiş sınıf adresine
dönüştürülebilir. Buradaki dönüştürme haklı bir dönüştürmedir. Bilindiği
gibi yukarıya ve aşağıya dönüştürme işlemeri aslında static_cast
operatörüyle yapılabilir. Ancak static_cast göstericinin gösterdiği yere
bakarak bu dönüştürmenin yerinde olup olmadığına bakmaz, halbuki
dynamic_cast RTTI özelliğini dikkate alarak eğer dönüştürme yerindeyse
bu işlemi yapar. dynamic_cast dönüştürmenin uygun olup olmadığını şöyle
belirler: RTTI mekanizmasını kullanarak dönüştürülecek türün
göstericinin gösterdiği gerçek tür içerisinde var olup olmadığını
araştırır. Eğer dönüştürülecek tür göstericinin gösterdiği yerdeki
gerçek bileşik türün parçalarından biriyse dönüştürme yerindedir ve
dynamic_cast dönüştürmeyi yapar. Örneğin şöyle bir türetme şeması olsun:














Şimdi D türünden bir nesne olsun bunun adresini doğrudan dönüştürme
yapmadan A türünden bir göstericiye atayabiliriz:

D d;
A *pA;
pA = &d;

Şimdi pA'nın B, C ve D türüne dönüştürülmesi uygun ve güvenli
işlemlerdir. Ancak E türüne dönüştürülmesi uygun ve güvenli değildir ve
gösterici hatasına yol açabilir. Çünkü A, B ve C, D nesnesinin
içerisinde vardır ama E nesnesi D'nin içerisinde yoktur. Ancak yine de
static_cast operatörüyle pA E türüne dönüştürülebilir.

E *pA = static_cast<E *>(pA);

Çünkü static_cast işleminde derleyici yalnızca ismi üzerinde static
olarak türetme şemasına bakmaktadır. Hâlbuki dynamic_cast dönüştürülecek
türün göstericinin gösterdiği gerçek nesne içerisinde olup olmadığına
bakarak dönüştürmeyi yapmaktadır. Tıpkı typeid operatöründe olduğu gibi
dynamic_cast operatöründe de doğru işlemlerin yapılabilmesi için
türetmenin çokbiçimli olması gerekir (yani tabandaki sınıfın en az bir
sanal fonksiyonunun olması gerekir). dynamic_cast dönüştürmeyi
yapabilirse dönüştürülmüş adrese, yapamazsa NULL değerine geri döner.
Örnek:


/* dynamic_cast. cpp */

#include <iostream>

using namespace std;

struct A {
public:
virtual ~A() {}
};
struct B : A {
};
struct C : B {
};
struct D : C {
};
struct E : A {
};
void main()
{
D d;
A *pA;

pA = &d;
C *pC;

pC = dynamic_cast<C *>(pA);
if (pC == NULL)
cout << "gecersiz donusturme\n";
else
cout << "gecerli donusturme\n";
}

Sayfa başına dön Aşağa gitmek
http://www.arenafutbol.org
 
c++ da operatörler
Sayfa başına dön 
1 sayfadaki 1 sayfası

Bu forumun müsaadesi var:Bu forumdaki mesajlara cevap veremezsiniz
ArenaFutbol | Futbol'a Dair Her Şey :: AF Cafe :: Eğlence :: Hazır Ödev ve Tezler :: Branş Dersleri-
Buraya geçin: