Co to jest wielokrotne ponowne dziedziczenie?
Nazywam to „wielokrotnym spadkiem”:
dziedziczenie klasy bezpośrednio i raz lub więcej razy pośrednio, dziedzicząc jednego lub więcej jej potomkówdziedziczenie klasy pośrednio dwa lub więcej razy poprzez dziedziczenie dwóch lub więcej jej potomkówChcę wiedzieć, czy istnieje i jak jednoznacznie uzyskać dostęp do osadzonych podobiektów.
1.) [Professional C ++, 2nd wyd.]† stwierdza, że program kompilowalny nie może mieć klasy, która bezpośrednio dziedziczy zarówno jego bezpośredniego rodzica, jak i klasę nadrzędną rodzica. Czy to prawda?
DawaćGrandParent
iParent
, który się rozszerzaGrandParent
, VC12 i g ++ pozwalają naGrandChild
bezpośrednio dziedziczyć po obuParent
iGrandParent
. W VC12 i g ++ możliwe jest zdefiniowanie tych klas w następujący sposób:
GrandParent
deklarujeint num
członek danych.Parent
deklaruje własnenum
oprócz dziedziczeniaGrandParent
jestnum
. GrandChild
deklaruje własnenum
oprócz dziedziczeniaParent
iGrandParent
jestnum
s.
Wydaje się, że VC12 umożliwia jednoznaczny dostęp do członków na całej planszy, ale g ++ zezwala na to tylko w niektórych przypadkach.
#include <iostream>
using std::cout;
using std::endl;
struct GrandParent { int num; };
struct Parent : GrandParent { int num; };
struct GrandChild : GrandParent, Parent { int num; };
int main()
{
GrandChild gc;
gc.num = 2;
gc.Parent::num = 1;
gc.Parent::GrandParent::num = 0; // g++ error: ‘GrandParent’ is an ambiguous base of ‘GrandChild’
gc.GrandParent::num = 5; // g++ error: ‘GrandParent’ is an ambiguous base of ‘GrandChild’
// --VC12 output; g++ output--
cout << gc.num << endl; // 2 ; 2
cout << gc.Parent::num << endl; // 1 ; 1
cout << gc.Parent::GrandParent::num << endl; // 0 ; N/A due to above error
cout << gc.GrandParent::num << endl; // 5 ; N/A due to above error
}
2.) Dlaczego (a)gc.Parent::GrandParent::num
niejednoznaczne w g ++, gdy (b)gc.Parent::num
nie? (a) jednoznacznie opisuje swoje położenie na drzewie dziedziczenia.gc
ma tylko 1Parent
podobiekt, który ma tylko 1GrandParent
podobiekt, który ma tylko 1num
. Dla (b),gc
ma jedenParent
, który ma swój własnynum
ale także aGrandParent
obiekt podrzędny z innymnum
.
3.) Dlagc.GrandParent::num
, wydaje się, że VC12 się temu przyglądagc
natychmiastGrandParent
podobiekt bazowy dla tego ostatniegonum
. Zgaduję, że jest to jednoznaczne, ponieważ jest to wyszukiwanie nazw zakwalifikowane przezgc
, więc jednostka na prawo od.
jest szukany jako pierwszygc
zakres i najbardziej bezpośredniGrandParent
dogc
Zakres jest bezpośrednio odziedziczony, a nie pośrednio dziedziczony przezParent
. Czy się mylę?
4.) Dlaczego tak jestgc.GrandParent::num
dwuznaczne dla g ++ kiedygc.Parent::num
nie? Jeśli jedno jest niejednoznaczne, to czy oba nie powinny być równie dwuznaczne? Za poprzedniegogc
ma dwaGrandParent
s; i dla tego ostatniegoParent
ma 2num
s.
†Gregoire, Marc R. i in.Professional C ++, 2nd wyd. Indianapolis, IN: Wiley Pubishing, 2011. str. 241. Drukuj.