so, ich werd mal versuchen, das zu erklären, hier wurden ein paar sachen vermischt:
Prinzipiell versucht man, die Abhängigkeiten zwischen verschiedenen Sourcecodemodulen so gering wie möglich zu halten - ganz speziell zwischen Headerdateien. In C++ ist das extrem wichtig, weil ansonsten die Compilezeiten drastisch anwachsen können.
Um das zu erreichen, gibt es u.a. das Prinzip der (forward) declarations, mit dem eine Name eingebracht wird. Dieser muss, sozusagen bevor er verwendet wird, noch definiert werden (--> definition), d.h., der Typ wird um seine Definition vervollständigt. Um sich das vorstellen zu können, muss man noch folgendes wissen: wenn C++-Code übersetzt wird, läuft dieser zuerst durch den Präprozessor, dann erst durch den Compiler. Der Präprozessor wandelt alle preprocessor directives (z.B. #include ... oder #pragma ... oder #define ...) um und ersetzt sofort alle Verwendungen von Makros (#define) im Code. Den Output des ganzen bezeichnen wir in C++ als translation unit, das ist also ein fertiges Stück Sourcecode ohne Abhängigkeiten zu anderen Dateien (die #include-Anweisungen sind vom Präprozessor durch den Inhalt der entspr. Dateien ersetzt worden!)
Jetzt bleibt noch die Frage (um die's hier geht), wo man die definition braucht und wo die declaration genügt:
Prinzipiell kann man in einem Header die definition immer "verstecken" (=weglassen), (unter anderem) wenn man
- einen Pointer auf den Typ deklariert
- eine Referenz auf den Typ deklariert
Der Grund dafür ist logisch: ein Pointer und eine Referenz sind immer gleich groß, ganz egal, welches Objekt sich dahinter verbirgt! D.h., dass der Compiler die Klassenstruktur von A nicht kennen muss, wenn ich z.B. folgendes
A *p_a;
A &r_a;
A const* pc_a;
deklariere.
Das ganze hat auch eine Patternmäßige Ausprägung, wenn bei sehr komplexen Strukturen gezielt versucht wird, die Implementierung zu verstecken und heißt "pimpl idiom" (mix aus "pointer" und "implementation").
Wo brauche ich jetzt die Definition? Überall, wo ich auf die Klasseninterna zugreife, also z.B., wenn in der zur Header gehörigen CPP-Datei die Methoden definiert werden (auch wieder so was, weil im Header wurden sie ja nur deklariert, für Funktionen gilt also das gleiche!)
#include "class_a.h"
A::A() {
}
oder aber z.B. beim Aufruf von Methoden von A (in x.cpp).
Zum letzten Fehler: using namespace ... gilt, wie der Name sagt, für die Benutzung von Namespaceelementen, nicht für deren Deklaration! D.h., die Methodendeklarationen entweder als
Loader::Camera::Camera() {...}
oder schöner
namespace Loader {
Camera::Camera() {...}
}
Hoffe, die Infos helfen!
Stefan
ISO C++ Standardisierung