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ów

Chcę 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 dziedziczeniaGrandParentjestnum. GrandChild deklaruje własnenum oprócz dziedziczeniaParentiGrandParentjestnums.

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ądagcnatychmiastGrandParent 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 pierwszygczakres i najbardziej bezpośredniGrandParent dogcZakres 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 dwaGrandParents; i dla tego ostatniegoParent ma 2nums.

†Gregoire, Marc R. i in.Professional C ++, 2nd wyd. Indianapolis, IN: Wiley Pubishing, 2011. str. 241. Drukuj.

questionAnswers(2)

yourAnswerToTheQuestion