C++ Sanal Oluşturucu

C Sanal Olusturucu



C++, sınıfın yapıcısını geçersiz kılmak mümkün olmadığından sanal kurucular oluşturmamızı kolaylaştırmaz. Dolayısıyla yapıcı sanallaştırmanın bir anlamı yoktur. C++ programında sanal kurucu oluşturma kavramı yoktur, ancak sanal yıkıcıyı orada oluşturabiliriz. Bunu ayrıca C++'da bir kurucu programlamak sanal olarak kabul edilemeyeceği için de tanımlayabiliriz, çünkü bir sınıfın kurucusu çağrıldığında bellekte sanal bir işaretçinin oluşturulmadığını gösteren hiçbir sanal tablo bulunmaz. Bu nedenle yapıcının her zaman sanal olmaması gerekir.

Ancak sanal bir yıkıcı mevcut olabilir. Burada, C++'da sanal bir kurucu oluşturduğumuzda ne olacağını ve sanal kurucu yerine sanal yıkıcının çalışmalarını göstereceğiz.

Örnek 1:

Sanal kurucuyu oluşturalım ve “iostream” başlık dosyasını yerleştirerek kodumuza başlayalım. Bu başlık dosyası, içinde “cin” ve “cout” gibi bildirilen işlevler içindir. Bundan sonra “std” namespace’ini ekliyoruz, dolayısıyla bu “std”yi kodumuzdaki her fonksiyona ekleyemiyoruz. Bundan sonra kodumuzun temel sınıfı olan “my_base” isminde bir sınıf oluşturup ardından “public” ekleyerek sanal kurucuyu oluşturuyoruz.







Sanal kurucu buraya “virtual” anahtar sözcüğünün yerleştirilmesiyle oluşturulur. Bu sanal kurucunun içine bir “cout” ifadesi yerleştiriyoruz. Bunun altında yine “cout”u kullandığımız “show” isimli bir fonksiyon oluşturuyoruz. Daha sonra bu temel sınıftan “my_derived” ismiyle türetilmiş bir sınıf oluşturuyoruz ve ardından “public” alanına “my_derived()” yapıcısını kuruyoruz. Bu “my_derived()” yapıcısına bir “cout” ifadesi ekliyoruz. Altına ise yine “cout”tan faydalanacağımız “show” adında bir fonksiyon oluşturuyoruz.



Şimdi “main()” komutunu çağırdıktan sonra, temel sınıfın “my_ptr” adında bir işaretçisini ve ayrıca türetilmiş sınıfın “Obj_d” nesnesini yaratıyoruz. Bundan sonra “Obj_d”nin adresini “my_ptr”e atıyoruz. Daha sonra “my_ptr” üzerinden “show()” fonksiyonunu çağırıyoruz.



Kod 1:





#include
kullanarak ad alanı std ;
sınıf benim_base
{
halk :
sanal benim_base ( )
{
cout << 'İşte benim temel sınıfım' << sonunda ;
}
geçersiz göstermek ( )
{
cout << 'temel sınıfın gösteri işlevi' << sonunda ;
}
} ;
sınıf my_derived : halk benim_base
{
halk :
my_derived ( )
{
cout << 'İşte türetilmiş sınıfım' << sonunda ;
}
geçersiz göstermek ( )
{
cout << 'türetilmiş sınıfın gösteri işlevi' < göstermek ( ) ;
}

Çıktı:
Burada, C++ programlamasında yapıcının sanal olarak tanımlanamayacağını belirten bir hata mesajı görüntülenir. Yani, C++'ın sanal kurucuyu oluşturmamıza izin vermediğini görebiliriz ancak sanal yıkıcıyı yaratabiliriz.



Örnek 2:

Bir önceki sorunu çözelim ve bu kodda sanal yıkıcıyı oluşturalım. “new_base” sınıfını deklare ettikten sonra “new_base” ile “virtual ~”ı ekleyerek sanal yıkıcıyı oluşturduğumuz “public” yapıcısını yerleştiriyoruz. Bu sanal yıkıcıya bir “cout” ifadesi ekliyoruz. Altında “cout” kelimesini kullanan “show” adında bir fonksiyon oluşturuyoruz. Daha sonra bu “new_base” temel sınıfın “new_derived” olan türetilmiş bir sınıfını oluşturuyoruz ve “public” alanına “new_derived()” yıkıcısını inşa ediyoruz. Bu 'new_derived()' yıkıcısına artık bir 'cout' ifadesi eklenmiştir.

Altında yine “cout” ifadesini kullanan “show” adında bir fonksiyon oluşturuyoruz. “main()” fonksiyonunu çağırdıktan sonra artık “obj_d” sınıfından türetilmiş bir nesnenin yanı sıra “ptr1” isimli temel sınıfın bir işaretçisini de üretiyoruz. Daha sonra “ptr1”e “obj_d” adresini veriyoruz. Daha sonra “ptr1” kullanılarak “show()” yöntemi çağrılır.

Kod 2:

#include
kullanarak ad alanı std ;
sınıf yeni_base
{
halk :
sanal ~new_base ( )
{
cout << 'Temel sınıf yıkıcı burada' << sonunda ;
}
geçersiz göstermek ( )
{
cout << 'Temel sınıfın gösteri işlevi' << sonunda ;
}
} ;
sınıf yeni_derived : halk yeni_base
{
halk :
~new_derived ( )
{
cout << 'Türetilmiş sınıf yıkıcı burada' << sonunda ;
}
geçersiz göstermek ( )
{
cout << 'Temel sınıfın gösteri işlevi' < göstermek ( ) ;
}

Çıktı:
Bu program, “obj_d”den türetilmiş sınıfa işaret eden “new_base”in bir işaretçi nesnesini kullanır. Böylece ilk olarak “new_base” sınıfının “show()” metodunu çağırır. Daha sonra “new_derived” sınıfının “~new_derived()” yöntemini çağırır ve temel sınıfın “~new_base” değerini görüntüler.

Örnek 3:

İşte 'sanal' kurucuyu oluşturmak için başka bir kod. “iostream” ve “std” ad alanını dahil ettikten sonra bir “B” sınıfı oluşturuyoruz. Bunun altında “B()” olan “public” yapıcıyı yaratıyoruz ve ardından “cout”u üretiyoruz. Yapıcı ve yıkıcı işlevler, sınıftaki herhangi bir nesnenin çağrılabileceği bir 'genel' erişim belirteci kullanılarak tanımlanır.

Şimdi yine “cout” kullandığımız bu temel sınıfın “~B()” yıkıcısını da oluşturuyoruz. Daha sonra “B” temel sınıfının türetilmiş sınıfı olan “D” sınıfını oluşturup buraya “public”i yerleştiriyoruz. Bu 'public'in içinde, sırasıyla 'D()' ve '~D' adlarıyla türetilmiş sınıfın yapıcısını ve yıkıcısını yaratıyoruz. Her ikisinin de içinde “cout” var. Artık “main()” fonksiyonumuz var. Bu fonksiyonu çağırdıktan sonra temel sınıfın işaretçi nesnesini oluşturuyoruz.

Daha sonra “delete” anahtar kelimesini kullanıp buraya “base_ptr” yerleştiriyoruz. Bu durumda, temel sınıfın işaretçi nesnesi çağrılarak yıkıcının alanı silinir.

Kod 3:

#include
kullanarak ad alanı std ;
sınıf B
{
halk :
B ( )
{
cout << 'Temel sınıfın Oluşturucusu' << sonunda ;
}
~B ( )
{
cout << 'Temel sınıfın yıkıcısı' << sonunda ;
}
} ;

sınıf D : halk B
{
halk :
D ( )
{
cout << 'Türetilmiş sınıfın Oluşturucusu' << sonunda ;
}
~D ( )
{
cout << 'Türetilmiş sınıfın yıkıcısı' << sonunda ;
}
} ;
int ana ( )
{
B * base_ptr = yeni D ;
silmek base_ptr ;
}

Çıktı:
Sonuç, ana fonksiyonda “B” sınıfını işaret eden bir işaretçi nesnesi kullandığını göstermektedir. Bu nedenle ilk önce “B” sınıfının “constructor()”unu çağırır. Daha sonra “D” sınıfının “constructor()”unu çağırır. “B” ve “D” sınıflarının yıkıcıları tarafından tutulan işaretçi nesnesi daha sonra silinir. Program içerisinde “D” sınıfının yıkıcısını çağırmadan, “B” sınıfı işaretçisi yalnızca “B” sınıfının yıkıcısını ortadan kaldırır. Sonuç olarak programın belleği bozulur.

Çözüm

C++ programlamada “Sanal yapı” kavramını tartıştık. C++'da sanal kurucu oluşturamayacağımızı ancak kodlarımızda sanal yıkıcıyı yaratabileceğimizi keşfettik. Burada C++ programlamada sanal kurucuyu oluşturduğumuzda neler olduğunu ve kodlarımızdaki sanal yıkıcının çalışmalarını gösterdik. Yapıcının sanal olamayacağını ancak sınıfımızda sanal yıkıcıyı oluşturabileceğimizi öğrendik. Bu kılavuzda bazı örnekleri gösterdik ve bu kodları ayrıntılı olarak açıkladık.