Soyut Sınıflar ve Saf Sanal Fonksiyonlar

Soyut sınıflar jenerik yapılar oluşturmak için kullanılır. Bu şekilde daha çok özelleştirilmiş türetik sınıfların yazılabilmesi sağlanır. Soyut sınıflar sadece başka sınıflar için temel sınıf olarak kullanılabilir. Bu nedenle soyut sınıf tipini kullanarak nesne oluşturmak olanaksızdır.

İçeriğinde en az bir saf sanal fonksiyon barındıran sınıflara soyut sınıf denir. Soyut sınıflardan türetilen tüm sınıflar temel sınıfın tüm saf sanal fonksiyonlarını kullanmalıdır, aksi durumda bu sınıflar da soyut sınıf olurlar.

. CAnimal sınıfını örnek verelim. Bu sınıf sadece bazı genel fonksiyonları sağlar – CAnimal tipli nesneler pratik kullanım için fazla geneldir. Bu da CAnimal'ı soyut sınıflar için iyi bir örnek yapar:

class CAnimal
  {
public:
                      CAnimal();     // Yapıcı
   virtual void       Sound() = 0;   // Saf sanal fonksiyon
private:
   double             m_legs_count;  // Hayvanın bacak sayısı
  };

Burada Sound() fonksiyonu bir saf sanal fonksiyondur çünkü saf sanal fonksiyon belirteci PURE (=0) ile bildirilmiştir.

Saf sanal fonksiyonlar sadece PURE belirteci ayarlandığı için sanal fonksiyondur: (=NULL) veya (=0). Soyut sınıf bildirimi ve kullanımı için bir örnek:

class CAnimal
  {
public:
   virtual void       Sound()=NULL;   // PURE (saf) yöntem, türetik sınıf içinde iptal edilmelidir, CAnimal şimdi soyut durumda ve nesne olarak oluşturulamaz
  };
//--- Soyut sınıftan türetilmiş
class CCat : public CAnimal
 {
public:
  virtual void        Sound() { Print("Myau"); } // PURE yöntem iptal edildi, CCat artık soyut değil ve nesne olarak oluşturulabilir
 };
 
//--- Hatalı kullanım örnekleri
new CAnimal;         // 'CAnimal' hatası - derleyici "soyut sınıf somutlaştırılamaz" hatasına dönüş yapar
CAnimal some_animal; // 'CAnimal' hatası - derleyici "soyut sınıf somutlaştırılamaz" hatasına dönüş yapar
 
//--- Doğru kullanım örneği
new CCat;  // Hata yok - CCat sınıfı soyut değil
CCat cat;  // Hata yok - CCat sınıfı soyut değil

 
Soyut sınıflar üzerindeki kısıtlamalar

Bir soyut sınıfın yapıcı fonksiyonunun bir saf sanal fonksiyonu çağırması durumunda (doğrudan veya dolaylı olarak) sonuç tanımsızdır.

//+------------------------------------------------------------------+
//| Soyut baz sınıf                                                  |
//+------------------------------------------------------------------+
class CAnimal
  {
public:
   //--- Saf sanal fonksiyon
   virtual void      Sound(void)=NULL;
   //--- Fonksiyon
   void              CallSound(void) { Sound(); }
   //--- Yapıcı
   CAnimal()
    {
     //--- Sanal yöntem çağrısının açık şekli
     Sound();
     //--- Sanal yöntem çağrısının gizli şekli (üçüncü bir fonksiyon ile)
     CallSound();
     //--- Yapıcılar ve yıkıcılar türetik sınıf içinden çağrılan bir fonksiyon ile iptal edilseler bile,
     //--- veya sanal olsalar bile daima kendi fonksiyonlarını çağırırlar
     //--- çağrılan fonksiyon saf sanal ise,
     //--- çağrı kritik hataya sebep olacaktır: "saf sanal fonksiyon çağrısı"
    }
  };

Ama soyut sınıflardaki yapıcı ve yıkıcılar diğer fonksiyonları çağırabilirler.