DİKKAT: ANSWER TEMEL DÜZENLENMİŞTİR!Analiz sorunun
: Sen multiple inheritance with a diamond problem kullanıyorsunuz
. bir kez doğrudan (struct D: C,A
) ve iki kez dolaylı (C miras yoluyla):
Daha spesifik olarak, sizin yapısı D
aynı temel A
sınıf üç kez devralır. temel sınıfları sanal değildir zamanda, D. 11 C++ standart bölümü 3 farklı bir alt-nesneler 10,1/4-5 aramaları bu kafes:
Normalde, her A
üyesini, derleyiciye, atıfta bulunduğunuz 3 A
alt nesnesinden hangisini anlatan açık bir kalifikasyonla ayırırsınız. Bu, C++ 11 bölüm 10.1/5'da açıklanmıştır. Üyeler için sözdizimi D
kapsamı içinde A::a
, C::a
ve B::a
olmalıdır, her ikisi de önce dışardaysanız D::
olmalıdır.
Maalesef C++ 11 bölüm 10.2/5-6 üye ad arama mantığı doğrudan A
baz daima açık yeterlilik (hatta using
ifadeleri) rağmen, diğer dolaylı A
bazlar belirsiz hale getirecek olmasını sağlar.
Kesin çözüm:
sorun doğrudan temel sınıf kaynaklanır gibi
ve diğerlerinden bu bir diambiguate için hiçbir yolu vardır aslında, sadece gerçekten çalışma çözüm boş kullanmaktır MSVC2013, clang 3.4.1 ve gcc 4.9 ile
struct Ob{ int v; }; // v aded here to allow verification of copy of all members
struct A { Ob a; };
struct B : A { Ob b; };
struct A1 : A {}; // intermediary class just for diambiguation of A in C
struct C : A1, B { Ob c; }; // use A1 instead of A
struct A2 : A { }; // intermediary class just for diambiguation of A in D
struct D : C, A2 { // use A2 instead of A
Ob d;
D() { }
D(const D& _d) : C(_d), A2(_d), d(_d.d) { }
};
int main(int ac, char**av)
{
cout << "Multiple inheritance\n";
D x;
x.A2::a.v = 1; // without A2:: it's ambiguous
x.A1::a.v = 2; // without A1:: it's ambiguous
x.B::a.v = 3;
x.b.v = 4;
x.d.v = 5;
D y = x;
cout << "The moment of truth: if not 1 2 3 4 5, there's a problem!\n";
cout << y.A2::a.v << endl;
cout << y.A1::a.v << endl;
cout << y.B::a.v << endl;
cout << y.b.v << endl;
cout << y.d.v << endl;
}
Bu kod derler ve işi: Arabulucu sınıfı farklı bir ad zorlamak için.
Diğer (olmayan) çözümleri:
Benim önceki cevabı sadece açık yeterlilik dayanıyordu. Birçok eleştiriye rağmen, MSVC2013'te gerçekten derlenmiş ve başarıyla test edilmiştir. Ancak, garip bir şeydi: Editörün zekasında bir belirsizlik vardı, ancak derleme herhangi bir hata olmadan gayet iyiydi. Bunun bir intelisence hatası olduğunu düşündüm, ama şimdi bunun bir derleyici olmayan uyum olduğunu fark ettin (hata?)
D(const D& other) : C(other), A((const B)other), d(other.d)
derlemesi yanıt veriyor ama testi geçmiyor. Niye ya ? Çünkü A((const B)other)
, other
'u B
olarak anlayacaktır. Bu nedenle D
numaralı telefondan A
doğrudan B
'dan (A
) başka bir şekilde alınan A
değeri ile başlatılacaktır. Bu son derece iğrenç bir hatadır ve farkına varmam biraz zaman aldı.
Tabii ki sanal temel sınıflarını kullanabilirsiniz. Daha sonra, birçok problemi çözen, D'de sadece tek bir A
alt nesne olacaktır.Ancak ne tasarladığınızı ben çizmiyorum ve bazı tasarımlar sanallaştırılmış bir elmastan ziyade bir kafes gerektiriyor.
İki adımlı bir kopyayı (adım 1: tablonun varsayılan olarak başlatılması; 2. adım: hedef değerin üssün üzerine kopyalanması) karşılayabiliyorsanız, doğru tablonun referansını döndüren farklı yönlendirme işlevlerini kullanan yaklaşımlar vardır. Ancak bu, yukarıda sunulan basit çözümden daha zor ve hataya eğilimli olabilir.
Tam derleyici hata mesajını ekleyebilir misiniz? – Angew
Ohh Anladım, yee derleyici hatası plz. –
Belki bu yararlıdır: http://stackoverflow.com/questions/6488772/refer-base-class-members-from-derived-class – Jack