P
hboy schrieb:
Ich kann zwar noch nicht so ganz akzeptieren, dass eine forward declaration vollkommen legitim ist, wenn keine eigentliche Deklaration folgt,
Warum nicht? Im Header von Klasse A ist die Definition von C völlig uninteressant. Auch die friend-Deklaration ist uninteressant. Sie muss nur syntaktisch korrekt sein, damit der Compiler nicht stolpert. An der Stelle merkt er sich aber eh nur "ok, A hat n Freund". Erst bei der Definition der Methode(n) von C, die auf die geschützten Methoden von A zugreifen, fällt ihm auf "Hey, das ist geschützt, darf es das? Ok, A hat es als Freund deklariert, es darf".
Grundsätzlich sind Deklarationen ohne passende Definition hinterher sowas von üblich - schau dir mal die ganzen Header an. Die meisten deklarieren einen Haufen von Funktionen und Methoden. Wenn die nicht grade inline definiert werden, werden diese Funktionen in allen bis auf genau einer Übersetzungseinheit, die den Header einbinden, nur deklariert und nicht definiert. Das ist mit Klassen nichts anderes. Dient alles nur dazu, dem Compiler zu sagen "hey, merk dir mal das Symbol hier, nicht dass du dich später wunderst wenn ich es benutze".
Worin unterscheidet sich nun die Variante 1
von Variante 2 ?
Variante 2 beeutet wie du richtig angenommen hast, dass auch Klasse A im globalen namespace liegt. Friend-Deklarationen ohne voll qualifizierten Namen (d.h. ohne Nennung des Namespace) gehen davon aus, dass die genannte Klasse (C) im gleichen Namespace liegt wie die nennde Klasse (A). [Das ist der Grund, warum du in Variante 2 C statt ::C nennen kannst, da C und A beide im globalen ns liegen]. Wenn so eine Klasse vorher noch nicht deklariert wurde, geschieht das implizit. [Das ist der Grund, warum Variante 2 ohne forward-Deklaration funktioniert]
Liegt die genannte Klasse in einem anderen Namespace muss sie also voll qualifiziert werden [also ::C], und da die implizite Namens-"injektion" nur im gleichen Namespace funktioniert, muss sie dann auch vorher (forward-)deklariert werden.