Was ist Mehrfachvererbung?
Ich bezeichne das Folgende als "mehrfache Neuvererbung":
Eine Klasse einmal direkt und ein oder mehrere Male indirekt erben, indem Sie einen oder mehrere ihrer Nachkommen erbenIndirektes zweimaliges Erben einer Klasse durch Erben von zwei oder mehr ihrer NachkommenIch möchte wissen, ob es existiert und wie eindeutig auf eingebettete Unterobjekte zugegriffen werden kann.
1.) [Professionelles C ++, 2nd ed.]† besagt, dass ein kompilierbares Programm keine Klasse haben kann, die direkt sowohl die unmittelbare Elternklasse als auch die Elternklasse des Elternteils erbt. Ist es wahr?
AngenommenGrandParent
undParent
, was sich erstrecktGrandParent
, VC12 und g ++ erlauben aGrandChild
direkt von beiden erbenParent
undGrandParent
. In VC12 und g ++ können diese Klassen wie folgt definiert werden:
GrandParent
erklärt eineint num
Datenelement.Parent
erklärt seine eigenennum
zusätzlich zum erbenGrandParent
'snum
. GrandChild
erklärt seine eigenennum
zusätzlich zum erbenParent
undGrandParent
'snum
s.
VC12 scheint einen eindeutigen Mitgliederzugriff auf der ganzen Linie zu ermöglichen, aber g ++ lässt dies nur in einigen Fällen zu.
#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.) Warum ist (a)gc.Parent::GrandParent::num
mehrdeutig in g ++ wenn (b)gc.Parent::num
ist nicht? (a) beschreibt seine Position im Vererbungsbaum eindeutig.gc
hat nur 1Parent
Unterobjekt, das nur 1 hatGrandParent
Unterobjekt, das nur 1 hatnum
. Für (b)gc
hat einenParent
, die ihre eigenen hatnum
aber auch aGrandParent
Unterobjekt mit einem anderennum
.
3.) Fürgc.GrandParent::num
, es scheint, dass VC12 untersuchtgc
ist sofortGrandParent
Basis-Unterobjekt für letzteresnum
. Ich vermute, der Grund für die Eindeutigkeit ist, dass es sich um eine Namenssuche handelt, die durch qualifiziert istgc
, also die Rechtsperson von.
wird zuerst in gesuchtgc
Umfang und die unmittelbarsteGrandParent
zugc
Der Geltungsbereich ist der direkt vererbte, nicht der indirekt vererbte überParent
. Liege ich falsch?
4.) Warum istgc.GrandParent::num
mehrdeutig zu g ++ wenngc.Parent::num
ist nicht? Wenn man mehrdeutig ist, sollten dann nicht beide gleich mehrdeutig sein? Für den Prior,gc
hat zweiGrandParent
s; und für letztereParent
hat 2num
s.
†Gregoire, Marc R. et al.Professionelles C ++, 2nd ed. Indianapolis, IN: Wiley Pubishing, 2011. p. 241. Drucken.