namespaces
-
Ich habe in meinem Projekt bis jz immer alles im globalen Namespace deklariert -wollte das jz aber ändern, weil es ja schon ein wenig übersichtlicher ist ^^ So weit, so gut, aber jz mein Problem:
irgend ne *.hpp:
//ifndef / define //benötigte system-includes (string / vector / ....) #include "clients.hpp" //namespace user //fkt werden definiert... std::string GetPreisStringFromInt (const user::GELD &v); //Compiler-FEHLER -> user ist kein namespace -.- //endifclients.hpp
//ifndef / define //system-includes (string + vector + iterator) #include "threads.hpp" //client-klasse erbt ja von threads #include "sock.hpp" //da ist die obere datei wieder eingebunden - das kommt aber öfters vor, dass es so einen "Kreis" gibt //weitere includes... namespace user { /*viele andere Namespaces, const-Werte bzw typedef's*/ }; class clientclass { public: class client { /*...*/ }; /*...*/ }; namespace user { /*noch paar Iteratoren usw als typedefs, damit ich ne immer so viel tippen muss ;) */ };Hab ich hier irgendwas grundlegendes falsch gemacht? Oo
Das komisch ist ja, dass die IDE weiß, dass user nen namespace ist (synthax-vervollständigung und beim mauszeiger drüberhalten etc) - der compiler aber nicht mehr :<IDE: VS 2005: Teamsuite
OS: Win XP ProfDanke...
-
class clientclass { public: class client=>
class client_class : public class...
-
1. Hat das was damit zu tun?
2. Ist die Klasse clientclass nur da, um die klasse client zu verwalten, das heißt, es sieht in etwa so aus:class clientclass { public: class client { //alle möglichen fkt / ... von client }; client * GetClientByUID (const user::ID& _uid) const; //client blabla entfernen usw. std::vector <client *> Clients; }; clientclass MyGlobalClientClassToTreatAllClients; //^^ nat. nenn ich meine Variablen nicht so ^^Oder hab ich da nen Denkfehler? Oo
-
unskilled schrieb:
1. Hat das was damit zu tun?
(D)Evil ist wohl nur ein Flüchtigkeitsfehler passiert. IdR schreibt man deine
public: class Xnämlich in zwei Zeilen.Andererseits ist es ein bisschen seltsam, dass du eine Klasse
clientclassnennst, die einzelneclientsproduziert. Sieht eher ein bisschen nach einerclientfactoryoder einclientmanageraus. undclientmuss auch nicht unbedingt eine Subklasse sein.Zu deinem Problem: Wo ist user::GELD definiert? Und in welchem
namespaceliegtGetPreisStringFromInt?
-
unskilled schrieb:
irgend ne *.hpp:
//ifndef / define //benötigte system-includes (string / vector / ....) #include "clients.hpp" //namespace user //fkt werden definiert... std::string GetPreisStringFromInt (const user::GELD &v); //Compiler-FEHLER -> user ist kein namespace -.- //endifOh, jetzt passiert mir auch noch so ein Fehler. Das ist der Inhalt einer Header-Datei? In Headern solltest du keine Funktionen definieren.
Zyklisches Einbinden von Headern sollte - wenn du Include-Guards verwendest - kein Problem darstellen. Nur: Warum brauchst du in clients.hpp den Code aus dem anderen Header?
-
ja - clientmanager würde vll eher hinkommen ^^
ich weiß, dass client keine subklasse sein muss, aber ich fand (und finde) es so eigtl schöner ^^
user::GELD:
clients.hpp://ifndef + define //systemincludes //restliche includes namespace user { typedef unsigned __int16 GELD; //....etc"Und in welchem namespace liegt GetPreisStringFromInt?"
Vorerst im globalen...//edit:
"Das ist der Inhalt einer Header-Datei?" Ja
"In Headern solltest du keine Funktionen definieren." Ich habe sie nur deklariert - definiert ist sie in der *.cpp"Zyklisches Einbinden von Headern sollte - wenn du Include-Guards verwendest - kein Problem darstellen." Gut
"Nur: Warum brauchst du in clients.hpp den Code aus dem anderen Header?"
Nein - ich brauch eine andere, eine '*2.hpp' in der 'clients.hpp' - die braucht die '*.hpp' (weil dort auch IntToString und StringToInt-Fkt drin sind) - deshalb dieses zyklische Einbinden, was ja aber (wie bereits festgestellt) kein Problem darstellen sollte?Danke schon mal
-
OK, clientclass und client haben jetzt aber nicht wirklich was mit deinem Problem zu tun, oder?
Mal zusammengefasst.
//sock.hpp #ifndef SOCK_HPP #define SOCK_HPP #include "clients.hpp" std::string GetPreisStringFromInt (const user::GELD &v); #endif //SOCK_HPP //clients.hpp #ifndef CLIENTS_HPP #define CLIENTS_HPP #include "sock.hpp namespace user { typedef x GELD; } #endif //CLIENTS_HPPJetzt kommt's natürlich darauf an, was du zuerst einbindest. Wenn du clients.hpp einbindest, dann wird zunächst sock.hpp eingebunden, in sock.hpp wird clients.hpp aber nicht eingebunden, weil CLIENTS_HPP schon definiert ist. D.h. in sock.hpp ist der
namespaceuser nicht dabei.
Wenn du aber zuerst sock.hpp einbindest, dann wird über sock.hpp zuerst client.hpp eingebunden, dernamespaceund die Definitionen sind da und du hast kein Problem, außer du verwendest in clients.hpp Definitionen aus sock.hpp.Alles klar?
-
unskilled schrieb:
Nein - ich brauch eine andere, eine '*2.hpp' in der 'clients.hpp' - die braucht die '*.hpp' (weil dort auch IntToString und StringToInt-Fkt drin sind) - deshalb dieses zyklische Einbinden, was ja aber (wie bereits festgestellt) kein Problem darstellen sollte?
Nur: Warum brauchst du diese Funktionsdefinitionen in clients.hpp?
Die Funktionsdeklarationen wirst du doch wohl eher in einer *.cpp-Datei brauchen, wo du sie auch aufrufst. (Oder anders gesagt: Wieso brauchst du Funktionsdeklarationen in einem Header, wenn du diese Funktionen - hoffentlich - nicht verwendest?)
-
Ach verdammt - ich dachte, die Reihenfolge wäre jz egal - da hätt ich es ja auch so lassen können, wie davor - aber da musste ich eben immer überlegen, wo ich die datei jetzt genau includiere -.-
Gibts ne Alternative zum 'Nach-Reihenfolge-Includieren'?
//edit:
Du includierst also sobald das möglich ist in der *.cpp und nicht in der *.hpp?
-
Inkludiere da, wo du bestimmte Definitionen brauchst. Wenn du in einer Header-Datei z.B. eine Klasse von einer anderen Klasse aus einem anderen Header ableitest, bei Komposition, wasimmer.
Funktionsdefinitionen wirst du in einer Header-Datei nur selten brauchen (wenn du inline-Funktionen definierst z.B.) - aber andererseits hindert dich auch niemand daran, Funktionen mehrfach zu deklarieren (wenn du eine bestimmte Funktion wo brauchst und nicht gleich einen ganzen Header einbinden willst)
Alles zusammenführen solltest du erst bei der Implementierung. Das reduziert auch die Abhängigkeiten der Header untereinander.
-
ja - aber den Aufwand bei Änderungen (jz wäre es meist nur ein typedef und dann wär es überall, wo ich die fkt deklariert habe) - aber ist allemal besser, als nichts compiliert zu bekommen ^^
Also danke : >Byebye