Cumartesi, Temmuz 18, 2009

C++ Saf Sanal Fonksiyon

Son zamanlarda yapmayı düşündüğüm bir proje için kaynak kod incelemeye başladım. Bu iş oldukça yorucu ve sıkıcı, kodların içinde kaybolabiliyosunuz. Fakat kazancıda bir o kadar fazla. Bütün bunların yanında bilmediğiniz bir çok şeyle karşılaşabiliyosunuz ve öğrenmeniz gereken daha çok şeyin olduğunun farkına varıyosunuz. Bu yazıda öğrenmem gerektiğinin farkına vardığım bir konu ile ilgili (garip bi cümle oldu:)) Saf Sanal Fonksiyon.

C++’ın böyle bir özelliğinden “virtual int DeviceHeightFont(int points)=0;” fonksiyon tanımını görene kadar haberdar değildim. Görür görmez insanı öğrenmeye sevk eden en büyük dürtü olan “MERAK” uyandı içimde. İnternette aramaya başladım ve “Saf Sanal Fonksiyon” tanımına vakıf oldum.

Yavaş yavaş mevzuya giriş yapalım. Virtual(sanal) fonksiyonlar, bir sınıftaki fonksiyonun bu sınıfı(temel sınıf) miras alan başka sınıflar(türemiş sınıflar) tarafından farklı bir amaç için yeniden yazılmasını sağlamak için kullanılır. Ama bazen temel sınıftaki fonksiyonun yapması gereken herhangi bir mantıklı işlemi olmaya bilir. Bu durumda sanal fonksiyonu “Saf Sanal Fonksiyon” olarak tanımlarız. Eğer bir sınıf en az bir tane saf sanal fonksiyona sahipse bu sınıf soyut sınıf olur. Saf Sanal Fonksiyona aşağıdaki şekilde tanımlanır.

virtual tip fonksiyonIsmi ([parametreler]) = 0;

Bazı önemli noktalar:

  • Saf sanal fonksiyon türetilmiş bütün sınıflarda yeniden tanımlanmalıdır. Yoksa, derleyici-zamanlı hata oluşur.
  • En az bir saf sanal fonksiyon içeren sınıfa soyut “abstract” sınıf denir.
  • Soyut sınıflara ait nesne yaratılamaz ama soyut sınıflara işaret eden işaretçiler yada referansta bulunan referanslar yaratılabilir.
  • Soyut sınıflardan nesne oluşturamayız ama o sınıfın da kurucusu olabilir.
Örnek Program;


#include <iostream>

using namespace std;

class Parca
{
public:
//Saf Sanal Fonksiyon
virtual void parcaIsmiYaz()=0;
};
class Anakart: public Parca
{
public:
//Saf sanal fonksiyonlar yeniden tanımlanıyor (Madde 1)
void parcaIsmiYaz()
{
cout<<"Anakart"<<endl;
}
};
class Ram: public Parca
{
public:
//Saf sanal fonksiyonlar yeniden tanımlanıyor (Madde 1)
void parcaIsmiYaz()
{
cout<<"Ram"<<endl;
}
};

int main()
{
srand(time(NULL));
//Hata Soyut sınıftan nesne türetemeyiz.(Madde 3)
//Parca p;

//Soyunt sınıftan işaretçi türetilebilir.(Madde 3)
Parca *ptr;
Anakart a;
Ram r;

/*Çalışma Anı çok biçimliliği. Sanal fonksiyonun bize sağladığı
avantajlardan biri. Duruma göre "ptr" işaretcsinin hangi türden bir nesneyi
işaret edeceği çalışma anında belli olacak.*/
for (int i =0;i<9;i++)
{
if (rand()%2)
{
//Anakart
ptr = &a;

}
else
{
//Ram
ptr = &r;

}
ptr->parcaIsmiYaz();
}

return 0;
}

4 yorum:

venomous waste dedi ki...

Teşekkürler Esat bu yazın için, Ogre3D'de de karşıma bolca çıkan bu tarz yazım şekli hakkında az çok fikir sahibi olmuştum keza en temel fonksiyon bu şekilde tanımlanmıştı ama ne adını ne de detaylarını biliyordum... Nette ufak bi araştırmayla adını öğrendim. bu sefer "saf sanal fonksiyon" adı altında google'da arattım karşıma ilk seçenekte senin blog geldi :)Tebrikler :)

Esat ARSLAN dedi ki...

Sağol Alper işine yaramasına sevindim :)

Unknown dedi ki...

Merhabalar, web sitenin birinde sanal fonksiyona örnek olarak şu verilmiş anlamadığım kısımları açıklama imkanınız varmı.
site : http://www.bogotobogo.com/cplusplus/virtualfunctions.php
Örnek:

#include

class A {
public:
void f() {
std::cout << "A::f()" << std::endl;
}
};

class B: public A {
public:
void f() {
std::cout << "B::f()" << std::endl;
}
};

class C: public B {
public:
void f() {
std::cout << "C::f()" << std::endl;
}
};

class D: public C {
public:
// No f()
};

int main()
{
A *a = new A();
B *b = new B();
C *c = new C();
D *d = new D();

a->f(); // A::f()
b->f(); // B::f()
c->f(); // C::f()
d->f(); // C::f()

((B *)c)->f(); // B::f() soldaki kullanım şeklinide ben yeni gördüm açıklama imkanınız varmı ?
((A *)c)->f(); // A::f() aynı kullanım
((A *)b)->f(); // A::f() aynı kullanım

return 0;
}

Unknown dedi ki...

Aynı zamanda türemiş sınıflarda virtual anahtar kelimesi kullanımıyla ilgili bir bilginiz varmı bazı yerlerde kullanılıyor bazılarında ise kullanılmıyor etkisi nedir bilginiz varmı ? Çok teşekkürler şimdiden.