VIRTUAL NEDİR?


   VIRTUAL FUNCTION ( SANAL FONKSİYONLAR)


        Örneğin, dikdörtgen olarak tanımlı bir sınıfımız bulunsun.


        class dikdortgen { 

        public:

        int x,y;

        int boy,en;

        public:

        int alan();

        };

        int dikdortgen :: alan() {

        return en *boy;

        }


    Yukarıdaki bu tanıma uyan diğer bir iki boyutlu şekil ise, kare’dir. Bilindiği üzere kare kenarları birbirine eşit bir dikdörtgendir. O halde kare sınıfını aşağıdaki şekilde tanımlayabiliriz.


        class kare:public dikdörtgen{ // kare sınıfı, dikdörtgen sınıfından miras alır.

        public:

        int alan();

         };

         kare::alan(){

         return en * en ;

         }

         };


        Yukarıdaki kare sınıfında görüldüğü üzere, her kare’nin zaten sahip olduğu x,y koordinatları ve en, boy bilgisi yeniden kodlanmamış bu bilgiler miras ile alınmıştır. Alan hesaplamak için yazılan alan() fonksiyonu ise, yeniden yazılmıştır. Bunun sebebi kare sınıfında sadece tek kenar bilgisinin yeterli olması ve bu durumda alan hesabının değişmesidir.


        Yukarı atama işlemi sırasında yaşanan bir problem, yukarı yükleme işlemi sonrasında, nesnenin bir fonksiyonu çağırıldığında, ata sınıfından mı çocuk sınıfından mı fonksiyonun çalışacağıdır.
        Örneğin, yukarıdaki miras konusunu ele alalım. Dikdörtgen sınıfından bir nesne göstericisinin içerisine, kare sınıfından bir nesne atanmıştır. Şimdi bu atamadan sonra
       d->alan();
şeklinde bir fonksiyon çağırımı yapılırsa, acaba kare sınıfının mı, dikdörtgen sınıfının mı alan fonksiyonu çalışacaktır?
          Herhangi özel bir durum olmaksızın, yukarıda yazdığımız kodlar için, d->alan() çağrımı, ata sınıfında (base class, ancestor, parent) olan alan fonksiyonunu çalıştıracaktır.
           Peki acaba çocuk sınıftaki alan fonksiyonun çalışmasını isteseydik kodu nasıl değiştirmemiz gerekirdi? 
           Sınıf tanımı sırasında, ata sınıfta bulunan fonksiyonu tanımlarken başına virutal eklenmesi, bu sınıfın ileride bir şekilde üzerine yükleme yapıldığında (override), ve ayrıca yukarı atama yapıldığında (upcasting), üzerine yükleme yapılan fonksiyon tarafından çalıştırılacağıdır.
           Örnek olarak yukarıdaki sınıf tanımını aşağıdaki şekilde değiştirirsek,

     class dikdortgen{
     public:
     int x,y;
     int boy,en;
     public:
     virtual int alan(){
     return en*boy;
     }
     };
   Bu yeni tanımdan sonra yukarı atama yapılırsa,

      dikdörtgen *d = new kare();

    artık d göstericisinin alan fonksiyonu çağırıldığında,

       d->alan();

 çalışacak olan alan fonksiyonu, kare sınıfındaki alan fonksiyonudur. Çünkü dikdörtgen sınıfında bulunan alan fonksiyonu sanal bir fonksiyondur (virtual function).

Yorumlar

Bu blogdaki popüler yayınlar

LINKER (BAĞLAYICI) NEDİR?

GUI (GRAFİKSEL KULLANICI ARAYÜZÜ) NEDİR?

PROCESS VE THREAD ARASINDA FARK NEDİR?