ProgramlamaC++ Geliştirici

Sanal fonksiyonların ve sanal mirasın C++'da nasıl çalıştığını açıklar mısınız? Soyut bir arayüz ile sınıf tasarımında dikkat edilmesi gereken hususlar nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Sanal fonksiyonlar, türetilmiş sınıf nesnelerinin, temel sınıfın işaretçileri veya referansları üzerinden işlenebilmesini sağlayan polimorfizmi gerçekleştirir. Sanal bir fonksiyonu tanımlamak için virtual anahtar kelimesi kullanılır:

class Base { public: virtual void foo() { std::cout << "Base::foo"; } }; class Derived : public Base { public: void foo() override { std::cout << "Derived::foo"; } };

Base* türündeki bir işaretçi aracılığıyla foo() çağrısı, Derived nesnesine işaret ediyorsa Derived'teki implementasyonu çağırır.

Soyut sınıf, en az bir tamamen sanal fonksiyon içeren sınıftır:

class Interface { public: virtual void process() = 0; // tamamen sanal fonksiyon };

Sanal miras, elmas miras problemine (diamond problem) çözüm sunar:

class A { }; class B : virtual public A { }; class C : virtual public A { }; class D : public B, public C { };

Bu, D nesnesinde sadece bir tane temel sınıf A örneği olacağını garanti eder.

Çeldirici Soru

Sanal bir yıkıcı ile normal bir yıkıcı arasındaki fark nedir? Miras için tasarlanmışsa, yıkıcının sanal olması gerekir mi?

Cevap: Sanal bir yıkıcı, temel tipteki bir işaretçi üzerinden silme işlemi yapıldığında, türetilmiş sınıfın yıkıcısının çağrılmasını garanti eder. Bu, kaynakların doğru bir şekilde serbest bırakılması için önemlidir.

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

Eğer yıkıcı sanal değilse, delete BasePtr; çağrısı yapıldığında yalnızca Base'in yıkıcısı çağrılacak ve miras alınan alanların kaynakları serbest bırakılmayacaktır.

Konuyla ilgili gerçek hata örnekleri


Hikaye

Farklı araçlar için ortak bir sınıf arayüzü olan büyük bir finansal sistemde, sanal yıkıcı tanımlanmamıştı. Bir miras alanda dinamik bir kaynak kullanılıyordu. Temel tipteki bir işaretçi aracılığıyla nesne silindiğinde bellek sızıntısı oldu, bu yalnızca sanayi yükleme aşamasında bulundu.


Hikaye

Ekip, sanal miras kullanmadan çoklu miras kullandı. D sınıfı, ara sınıflar aracılığıyla A'yı iki kez miras aldı. Bu, durumun kopyalanmasına ve A'nın üyelerine erişimde hatalara yol açtı. Sadece statik analiz araçlarıyla yapılan bir denetimden sonra düzeltildi.


Hikaye

Bir günlük eklenti geliştirme projesinde, soyut bir sınıf kullanıldı ancak yıkıcı sanal yapılmadı. Arayüz işaretçisi aracılığıyla eklentiler silindiğinde, çağrılmayan türevlerin yıkıcılarıyla ilgili belirgin olmayan bağımlılıklar ve hatalar gözlemlendi. Sorun, kaynak havuzunu kapsıyor ve kaynak sızıntılarına yol açıyordu.