C++ Klasse / Dateien
-
Hallo,
ich weiß, die Frage kommt öfter und ich habe sie eigentlich glaube ich schon
selber gestellt, aber jetzt wird sie wichtig, weil ich Quellcode
veröffentlichen will (Ich bin ein ziemlicher Perfektionist!
). Also ich
habe eine Klasse (was für ein Wunder in C++
) und möchte jetzt wissen, wie
ich den Code jetzt verpacken soll, heißt: soll ich alles in eine Datei
schreiben, soll ich den Funktionskopf vom Rumpf trennen, oder zusammenlassen?Vielen Dank!
-
Normal kommt die Deklaration in den Header und der Code nur, wenn es inline sein soll.
-
Also eine *.cpp und eine *.h???
-
Korrekt,
außer templates, da lohnt sich eigentlich immer inline in der Header-Datei.
Also aufspaltung in .h und .tcc und #include "foo.tcc" am ende der Header-Datei lohnt sich imho nicht.Und zu .h und .cpp -> Eine Klasse pro Modul (.h+.cpp) ist *meistens* sinnvoll.
Edit: ein "nicht" im 2. Satz hinzugefügt.

-
Was ist denn *.tcc? Hab noch nie gehört.
Zu .h und .cpp:
Also:bla.h
// Code class bli { public: void bla(); }; // Codebla.cpp
// Code void bli::bla() { // blub } // CodeAber in welcher Dateien soll ich was inkludieren?
-
Beispiel ohne Templates mit strikter Trennung des Moduls in .h und .cpp -Datei:
// myclass.h #ifndef MYCLASS_H #define MYCLASS_H class MyClass { private: int m_i; public: MyClass(); ~MyClass(); void do_stuff(); // nicht inline, lohnt nich int get_count() const // inline sinnvoll { return m_i; } }; #endif // !MYCLASS_H// myclass.cpp MyClass::MyClass() : m_int(0) {} MyClass::~MyClass() {} void MyClass::do_stuff() { // manch was m_i++; // mach noch mehr // hier würde zu viel stehen, als dass sich inline lohnen würde }nun zur *.tcc, das gehört auch eigentlich nicht standardäßig zu C++ (soweit ich weiß), aber bspw. die STL-Implementation vom gcc (libstdc++) macht es so:
// mycontainer.h #ifndef MYCONTAINER_H #define MYCONTAINER_H template<class T> class MyContainer { private: T* m_ptr; public: MyContainer(size_t size); ~MyContainer(); }; // hier wird includiert #include "mycontainer.tcc" #endif // !MYCONTAINER_H// mycontainer.tcc template<class T> MyContainer::MyContainer(size_t size) { m_ptr = new T[size]; } template<class T> MyContainer::~MyContainer() { delete m_ptr; }.tcc kannst du dir als "template c++ (implementation) file" übersetzen, die für templates die Implementation in der Header-Datei stehen muss, du sie aber trotzdem in eine extra Datei (die aber nicht dem Kompiler mitgeteilt wird!) auslagerst.
natürlich könnte man den Ctor und Dtor beide inline direkt in die .h Datei schreiben. Könnte meistens sogar übersichtlicher sein. Ich denke, es kommt hier hauptsächlich auf den eigenen Geschmack an, weniger auf die Projektgröße. Höchstens noch die Klassengröße.
-
Aber wenn man im obieren Beispiel myclass.h in main.cpp inkludiert wird das doch
nicht mit myclass.cpp in Verbindung gebracht. Man muss doch irgendwo die myclass.cpp
inkludieren, oder?
-
Hä?
Ein weiteres Trivialbeispiel mit dem von oben:
// myclass.h #ifndef MYCLASS_H #define MYCLASS_H #include <string> class MyClass { private: // sichern, was zuletzt gesagt wurde std::string m_lastsaid; public: MyClass(); ~MyClass(); void say(const std::string& s); std::string last_said() const // inline { return m_lastsaid; } }; #endif // !MYCLASS_H//myclass.cpp #include <iostream> #include "myclass.h" MyClass::MyClass() : m_lastsaid("<nothing>") // initialisieren, keine ausgabe bisher {} MyClass::~MyClass() {} void MyClass::say(const std::string& s) { m_lastsaid = s; std::cout << m_lastsaid << std::endl; }// main.cpp // benutzung #include <iostream> #include "myclass.h" // eine HEADER (.h) Datei int main() { MyClass a; a.say("hello"); // hello auf dem bildschirm a.say("world"); // world auf dem bildschirm // ... letzte ausgabe? std::cout << a.last_said() << std::endl; // ausgabe: world if(a.last_said() == "hello") // false, weil letzte ausgabe world war std::cerr << "letzte ausgabe war nicht world"; // wird nie erreicht }MyClass gibt also mit MyClass::say() einen Text aus, und speichert diese letzte Meldung im std::string m_lastsaid. Es gibt eine .h und eine .cpp für die klasse und eine .cpp für int main().
diese machst du jetzt so dem Compiler (bspw. g++ bekannt)
g++ main.cpp myclass.cppEine .cpp muss nirgends inkludiert werden (!). Du machst sie entweder im Projekt deiner IDE, in deinem Makefile oder in der Kommandozeile deinem Compiler bekannt.
Am besten schaust du mal bei Google und der (englischen) Wikipedia nach Deklaration und Definition in der Programmierung, bzw. genauer bei C++ (und nebenbei noch C, schaden wirds nich).

Edit: schönheitsfehler
-
Also, du inkludierst im Hauptprogramm die Headerdatei. Die Funktionen an sich
sind in der *.cpp und dort wird die Header auch inkludiert. Wie funktioniert
denn das, dass man in der main.cpp dann auf die Funktionen zugreifen kann, wenn
sie doch eigentlich nicht inkludiert werden? Oder wird die *.cpp immer zum
Projekt hinzugefügt???Und noch eine Schönheitsfrage:
Zu der Klasse habe ich noch ein paar Konstanten und ein Enum. Soll ich das ganze
in einen Namespace verpacken????
-
Oh sry, hab deinen letzten Post nicht ganz durchgelesen.
-
D schrieb:
Und noch eine Schönheitsfrage:
Zu der Klasse habe ich noch ein paar Konstanten und ein Enum. Soll ich das ganze
in einen Namespace verpacken????Wenn die Klassen, Konstanten und Enums einen logischen Bezug zu einander haben, kannst du das gut in den gleichen Namespace packen.