2016-09-07 5 views
2

Ich habe eine Vererbung Problem bekam: Sagen wir, ichC++ Vererbung - mehrdeutige Funktion

class Time{ 
protected: 
void foo(); 
}; 

haben und auch

class Base: private Time{ 
void foo1(){ foo(); } 
}; 

class Child: public Base, private Time{ 
void foo2(){ foo(); }// here my compiler says that foo is ambiguous 
}; 

warum ist foo() nicht eindeutig, wenn das Erbe Die Zeit in Base ist privat?

PS. Nur & nur für diejenigen, die den vollständigen Code sehen müssen, hier ist das GitHub-Projekt: https://github.com/huntekah/Interior_decorator-OpenGL_Project/blob/master/Grafika-OpenGL/Interior_decorator/Display.cpp#L133 Klasse Zeit (Dienstprogramme Verzeichnis) wird von ControlObjects und ControlCamera geerbt, die beide die Basis für Controls sind. Display erbt Controls und zusätzlich Time. Kommentarzeile zeigt eine Stelle an, an der SetDeltaTime() mehrdeutig ist;

+0

private versteckt es nicht. – Jarod42

+0

Weil sowohl Base als auch Time eine Memberfunktion namens foo haben und der Compiler nicht weiß, welchen Sie aufrufen möchten. Da draußen ist irgendwo ein Betrüger. –

+0

wird Namespace innerhalb Base verstecken es? –

Antwort

0

Vorbemerkungen

Ihr Code-Snippet nicht aus einem anderen Grund nicht kompiliert: Base hat keinen Zugriff auf Time ‚s foo() wie es ein privates Mitglied ist. So verursacht die foo1() einen Fehler, bevor Sie die Mehrdeutigkeit gemeldet haben.

Wenn Sie Time ändern ihr Mitglied geschützt zu machen, dann können Sie Ihre Fehler reproduzieren genau so, wie Sie beschreiben:

class Time{ 
protected: 
    void foo(); 
}; 

Was hier los?

Base erbt privat Time, so dass seine Mitglieder nicht von außen sichtbar sein sollen.

Aber was für die externe Welt wahr sein könnte, gilt nicht für abgeleitete Klassen. Die Namenssuche Regeln im Fall der Ableitung sagen, dass zuerst der Name in der Klassenhierarchie aufsah, dann ist Überlastung angelegt, als nur Steuerzugriff durchgeführt:

10.2/1 Member name lookup determines the meaning of a name (id-expression) in a class scope. Name lookup can result in an ambiguity, in which case the program is ill-formed. For an id-expression, name lookup begins in the class scope of this; for a qualified-id, name lookup begins in the scope of the nested-name-specifier. Name lookup takes place before access control.
10.2/8 If the name of an overloaded function is unambiguously found, overloading resolution also takes place before access control. Ambiguities can often be resolved by qualifying a name with its class name.

Wie Sie Mehrfachvererbung verwenden:

Time  
    : 
    : 
Base Time 
    \ : 
    \ : 
    Child 

So erben Sie zweimal eine foo(), einmal über private Vererbung und onve über die Öffentlichkeit. Diese Mehrdeutigkeit macht den Namen foo in foo2() mehrdeutig gemäß dem Standard und bevor der Zugriff verifiziert wird, macht Ihren Code ungültig.

Beachten Sie, dass Kind 2 foo() sieht, aber ironischerweise kann keiner von ihnen verwenden: beide kommen über private geerbt. Selbst wenn Sie die Mehrdeutigkeit auflösen würden, erhalten Sie eine weitere Fehlermeldung zur Barrierefreiheit.

1

Es gibt einen weiteren Fehler in Ihrem Code: Klassenbasis erbt privat von Klasse Zeit und Klasse Child erbt wieder privat von Klassenzeit !!!

das Gesetz der Vererbung:

class Time 
{}; 

class Base : private Time 
{}; 

class Child : public Base, private Time 
{}; 

Base enthält eine Kopie der Klasse Zeit, weil es von ihr erbt.

child hat eine Kopie der Klasse Base, weil sie von ihr erbt.

*** Kind hat eine Kopie der Klasse Time, weil seine Eltern (Base) diese Kopie hat.

Wenn Child versucht, explizit von der Klasse zu erben, wird Time einen Kompilierzeitfehler ausgeben: Fehler C2584: 'Kind': direkte Basis 'Zeit' ist nicht zugänglich; bereits eine Basis von 'Base'