C++'da çoklu kalıtım güçlüdür, ancak dikkatli kullanılmadığında genellikle sorunlara yol açan, Elmas Problemi gibi problemlere yol açan zor bir araçtır.

Bu yazımızda Elmas Problemini, çoklu kalıtımdan nasıl kaynaklandığını ve sorunu çözmek için neler yapabileceğinizi ele alacağız.

C++'da Çoklu Kalıtım

Çoklu Kalıtım bir Nesneye Yönelik Programlamanın (OOP) özelliği burada bir alt sınıf birden fazla üst sınıftan miras alabilir. Başka bir deyişle, bir alt sınıfın birden fazla ebeveyni olabilir.

Aşağıdaki şekil, çoklu mirasın resimli bir temsilini göstermektedir.

Yukarıdaki diyagramda, C sınıfı vardır a sınıfı ve B sınıfı ebeveynleri olarak.

Gerçek bir yaşam senaryosu düşünürsek, bir çocuk babasından ve annesinden miras alır. Böylece bir Çocuk, ebeveynleri olarak “Baba” ve “Anne” ile türetilmiş bir sınıf olarak temsil edilebilir. Benzer şekilde, çoklu kalıtımın gerçek hayattan pek çok örneğine sahip olabiliriz.

Çoklu kalıtımda, kalıtılan bir sınıfın yapıcıları, kalıtıldıkları sırayla yürütülür. Öte yandan, yıkıcılar miraslarının tersi sırayla yürütülür.

instagram viewer

Şimdi çoklu kalıtımı gösterelim ve nesnelerin yapım ve imha sırasını doğrulayalım.

Çoklu Kalıtımın Kod Gösterimi

Çoklu kalıtım gösterimi için yukarıdaki gösterimi tam olarak C++ ile programladık. Programın kodu aşağıda verilmiştir.

#Dahil etmek
ad alanı std kullanarak;
A sınıfı // yapıcı ve yıkıcı ile temel A sınıfı
{
halka açık:
A() { cout << "sınıf A:: Yapıcı" << endl; }
~A() { cout << "sınıf A:: Yıkıcı" << endl; }
};
B sınıfı // yapıcı ve yıkıcı ile temel B sınıfı
{
halka açık:
B() { cout << "sınıf B:: Yapıcı" << endl; }
~B() { cout << "sınıf B:: Yıkıcı" << endl; }
};
C sınıfı: genel B, genel A // türetilmiş C sınıfı, A sınıfını ve ardından B sınıfını devralır (sıraya dikkat edin)
{
halka açık:
C() { cout << "sınıf C:: Yapıcı" << endl; }
~C() { cout << "sınıf C:: Yıkıcı" << endl; }
};
int ana(){
Cc;
0 döndür;
}

Yukarıdaki programdan elde ettiğimiz çıktı aşağıdaki gibidir:

B sınıfı:: Yapıcı
A sınıfı:: Yapıcı
C sınıfı:: Yapıcı
C sınıfı:: Yıkıcı
A sınıfı:: Yıkıcı
B sınıfı:: Yıkıcı

Şimdi çıktıyı kontrol edersek, yıkıcılar ters sırada iken yapıcıların B, A ve C sırasına göre çağrıldığını görüyoruz. Artık çoklu kalıtımın temellerini bildiğimize göre, Elmas Problemini tartışmaya geçiyoruz.

Elmas Problemi, Açıklandı

Elmas Problemi, bir alt sınıf, her ikisi de ortak bir büyük ebeveyn sınıfını paylaşan iki üst sınıftan miras aldığında ortaya çıkar. Bu, aşağıdaki şemada gösterilmektedir:

Burada bir sınıfımız var Çocuk sınıflardan miras alma Baba ve Anne. Bu iki sınıf, sırayla, sınıfı devralır. Kişi çünkü hem Baba hem de Anne Kişidir.

Şekilde gösterildiği gibi, Çocuk sınıfı, Kişi sınıfının özelliklerini, bir kez Babadan ve yine Anneden olmak üzere iki kez miras alır. Bu, derleyici hangi yöne gideceğini anlayamadığından belirsizliğe yol açar.

Bu senaryo elmas şeklinde bir kalıtım grafiğine yol açar ve ünlü olarak "Elmas Problemi" olarak adlandırılır.

Elmas Probleminin Kod Gösterimi

Aşağıda, yukarıdaki elmas şeklindeki kalıtım örneğini programlı olarak sunduk. Kod aşağıda verilmiştir:

#Dahil etmek
ad alanı std kullanarak;
sınıf Kişi { //sınıf Kişi
halka açık:
Kişi (int x) { cout << "Kişi:: Aranan kişi (int)" << endl; }
};
sınıf Babası: genel Kişi { //sınıf Babası Kişiyi devralır
halka açık:
Baba (int x):Kişi (x) {
cout << "Baba:: Baba (int) aradı" << endl;
}
};
class Mother: public Person { //class Mother, Kişiyi miras alır
halka açık:
Anne (int x):Kişi (x) {
cout << "Anne:: Anne (int) denir" << endl;
}
};
sınıf Çocuk: genel Baba, genel Anne { //Çocuk Baba ve Anneyi miras alır
halka açık:
Çocuk (int x):Anne (x), Baba (x) {
cout << "Çocuk:: Çocuk (int) olarak adlandırılır" << endl;
}
};
int ana() {
Çocuk çocuk (30);
}

Bu programın çıktısı aşağıdadır:

Kişi:: Aranan kişi (int)
Baba:: Baba (int) aradı
Kişi:: Aranan kişi (int)
Anne:: Anne (int) denir
Çocuk:: Aranan Çocuk (int)

Şimdi burada belirsizliği görebilirsiniz. Person sınıfı oluşturucusu iki kez çağrılır: bir kez Peder sınıfı nesnesi oluşturulduğunda ve ardından Mother sınıfı nesnesi oluşturulduğunda. Person sınıfının özellikleri iki kez miras alınır ve belirsizliğe neden olur.

Person sınıfı yapıcısı iki kez çağrıldığından, Child sınıfı nesnesi yok edildiğinde yıkıcı da iki kez çağrılır.

Şimdi sorunu doğru anladıysanız Elmas Probleminin çözümünü tartışalım.

C++'da Elmas Problemi Nasıl Onarılır

Elmas sorununun çözümü, gerçek anahtar kelime. Alt sınıfta büyük ebeveyn sınıfının iki kopyasını önlemek için iki ebeveyn sınıfı (aynı büyük ebeveyn sınıfından miras alan) sanal sınıflar haline getiriyoruz.

Yukarıdaki çizimi değiştirelim ve çıktıyı kontrol edelim:

Elmas Problemini Düzeltmek için Kod Çizimi

#Dahil etmek
ad alanı std kullanarak;
sınıf Kişi { //sınıf Kişi
halka açık:
Kişi() { cout << "Kişi:: Kişi() aradı" << endl; } //Temel kurucu
Kişi (int x) { cout << "Kişi:: Aranan kişi (int)" << endl; }
};
sınıf Baba: sanal genel Kişi { //sınıf Babası Kişiyi devralır
halka açık:
Baba (int x):Kişi (x) {
cout << "Baba:: Baba (int) aradı" << endl;
}
};
class Mother: virtual public Person { //class Mother, Kişiyi miras alır
halka açık:
Anne (int x):Kişi (x) {
cout << "Anne:: Anne (int) denir" << endl;
}
};
sınıf Çocuk: genel Baba, genel Anne { //sınıf Çocuk, Baba ve Anneyi miras alır
halka açık:
Çocuk (int x):Anne (x), Baba (x) {
cout << "Çocuk:: Çocuk (int) olarak adlandırılır" << endl;
}
};
int ana() {
Çocuk çocuk (30);
}

Burada kullandığımız gerçek Baba ve Anne sınıfları Kişi sınıfını devraldığında anahtar kelime. Buna genellikle "sanal kalıtım" denir ve bu, devralınan sınıfın (bu durumda, Person sınıfının) yalnızca tek bir örneğinin iletilmesini garanti eder.

Başka bir deyişle, Child sınıfı, hem Baba hem de Anne sınıfları tarafından paylaşılan Kişi sınıfının tek bir örneğine sahip olacaktır. Person sınıfının tek bir örneğine sahip olarak, belirsizlik çözülür.

Yukarıdaki kodun çıktısı aşağıda verilmiştir:

Kişi:: Kişi() aradı
Baba:: Baba (int) aradı
Anne:: Anne (int) denir
Çocuk:: Aranan Çocuk (int)

Burada, Person sınıfının kurucusunun yalnızca bir kez çağrıldığını görebilirsiniz.

Sanal kalıtım hakkında dikkat edilmesi gereken bir şey, Kişi sınıfı, başlatma yoluyla Baba ve Anne sınıfı oluşturucuları tarafından açıkça çağrılır listeler, sadece Person sınıfının temel kurucusu çağrılacak.

Bunun nedeni, ondan miras alan birden çok sınıf tarafından paylaşılan sanal bir temel sınıfın yalnızca tek bir örneğinin olmasıdır.

Temel oluşturucunun birden çok kez çalışmasını önlemek için, sanal bir temel sınıfın yapıcısı, ondan miras alan sınıf tarafından çağrılmaz. Bunun yerine, yapıcı, somut sınıfın yapıcısı tarafından çağrılır.

Yukarıdaki örnekte, Child sınıfı, Person sınıfı için doğrudan temel kurucuyu çağırır.

İlgili: C++'da Standart Şablon Kitaplığı için Başlangıç ​​Kılavuzu

Temel sınıfın parametreli yapıcısını çalıştırmanız gerekirse ne olur? Bunu, Baba veya Anne sınıfları yerine açıkça Çocuk sınıfında arayarak yapabilirsiniz.

C++'daki Elmas Problemi Çözüldü

Elmas Problemi, iki ebeveyn sınıfı aynı büyük ebeveyn sınıfından miras aldığında ve her iki ebeveyn sınıfı da tek bir alt sınıf tarafından miras alındığında çoklu kalıtımda ortaya çıkan bir belirsizliktir. Sanal kalıtım kullanılmadan alt sınıf, büyük ebeveyn sınıfının özelliklerini iki kez devralır ve bu da belirsizliğe yol açar.

Bu, gerçek dünya kodunda sık sık ortaya çıkabilir, bu nedenle bu belirsizliği tespit edildiğinde ele almak önemlidir.

Elmas Problemi, sanal kalıtım kullanılarak çözülmüştür. gerçek anahtar kelime, üst sınıflar paylaşılan bir büyük ebeveyn sınıfından miras aldığında kullanılır. Bunu yaparak, büyük ebeveyn sınıfının yalnızca bir kopyası yapılır ve büyük ebeveyn sınıfının nesne yapısı alt sınıf tarafından yapılır.

PaylaşCıvıldamakE-posta
Yeni Programcılar için En İyi 10 Başlangıç ​​Projesi

Programlama öğrenmek istiyor ama nereden başlayacağınızı bilmiyor musunuz? Bu başlangıç ​​seviyesindeki programlama projeleri ve eğitimleri sizi başlatacak.

Sonrakini Oku

İlgili konular
  • Programlama
  • C Programlama
Yazar hakkında
MUO Personeli

Haber bültenimize abone ol

Teknik ipuçları, incelemeler, ücretsiz e-kitaplar ve özel fırsatlar için bültenimize katılın!

Abone olmak için buraya tıklayın