namespace problem
-
wie schaffe ich es eine universelle namespace auf verschieden Klassen zu übertragen?
Ich bekomme immer einen Linker Fehler wenn ich#include "namspc.h"auf verschiedene Klassen include

Es kommt ein "already defined in" Fehler.
-
Beobachter01 schrieb:
wie schaffe ich es eine universelle namespace auf verschieden Klassen zu übertragen?
Übertragen? Sowas gibts nicht. Du kannst höchtens Klassen in einem namespace definieren.
Ich bekomme immer einen Linker Fehler wenn ich
#include "namspc.h"auf verschiedene Klassen include

Es kommt ein "already defined in" Fehler.
Dann liefere uns doch mal den kompletten Linkerfehler und ein wenig Code, um dein Problem zu verdeutlichen. Am Besten minimalen Code, der genau diesen Linkerfehler erzeugt. Wir können mit deinen bisherigen Angaben nur ins Blaue raten, und das führt zu nichts.
-
error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl dataPool::getValue(void)" (?getValue@dataPool@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) already defined in module1.obj Target.obj : error LNK2005: "class std::list<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >::_Iterator<1> dataPool::listenWerteIt" (?listenWerteIt@dataPool@@3V?$_Iterator@$00@?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@A) already defined in module1.obj Target.obj : error LNK2005: "class std::list<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > dataPool::listenWerte" (?listenWerte@dataPool@@3V?$list@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@A) already defined in module1.objDas ist der Fehler!
Ich wollte diese namespace von allen Klassen nutzbar machen. Aber wenn ich die Header-Datei mehr als einmal irgendwo include bekomme ich diesen Fehler!
Wie kann ich sonst so einen "Universellen" Speicher zu Verfügung stellen? Eine statische Klasse vielleicht? ich weiss es einfach nicht.
-
Da du immernoch keinen Code geliefert hast, muss ich immernoch raten. Ich nehme mal an, dass dataPool der namespace ist, um den es geht. Ich rate ferner mal, dass du in einem Header die Funktionen definiert hast, über die sich der Compiler hier beschwert. Ich rate außerdem, dass du sie nicht inline definiert hast und den header in mehreren Übersetzungseinheiten einbindest, nämlich module1.cpp und Target.cpp. Dadurch verletzt du die ODR (One Definition Rule).
Lösung 1: in den header sollte nur die Deklaration der Funktionen, nicht die Definition. Die Definition muss dagegen in eine eigene .cpp
Lösung 2: Wenn es auf keinen Fall eine .cpp geben soll (z.B. weil du ein Header-only Framework schreibst), definiere die Funktionen als inline. Ich tippe mal, dass die Bedingung für Lösung 2 nicht zutrifft.btw: Das hat mit dem namespace nichts zu tun. Wäre auch passiert, wenn du die Funktionen ohne umschließenden Namespace im header definiert hättet.
-
Sorry, ich hatte den Code vergessen hinzufügen
//ist di namesp.h std::list<std::string> liste template<typename T> void setValue(double t, int i, T wert); //namesp.cpp template<typename T> void setValue(double t, int i, T wert) { std::stringstream ss; ss<<t<<"\n"<<i<<"\n"<<wert<<"\n"; liste.push_front(ss.str()); }
-
Das ist nicht der Code, der den Fehler erzeugt hat. Du zeigst hier setValue-Templates, die Fehler beziehen sich auf getValue, litenWerteIt, listenWerte.
Bei Templates ists übrigens genau andersrum, die musst du komplett im Header definieren, das geht auch ohne inline, da bei Templates die ODR nicht greift.
-
Sorry ich dachte das die keine Rolle spielt. Also nochmal
//ist di namesp.h namespace bla{ std::list<std::string> liste std::list<std::string>::iterator listIt template<typename T> void setValue(double t, int i, T wert); std::string getValue(); } //namesp.cpp template<typename T> void bla::setValue(double t, int i, T wert) { std::stringstream ss; ss<<t<<"\n"<<i<<"\n"<<wert<<"\n"; liste.push_front(ss.str()); } std::string bla::dataPool::getValue(){ listIt = listenWerte.begin(); std::string wert = *listIt; return wert; }listenWerte entspricht liste, listenWerteIt entspricht listIt
-
- getValue hat genau das Problem, was ich oben beschrieben habe.
- liste und listIt sind mit Sicherheit nicht so definiert, sonst würde es nichtmal durch den Compiler gehen.
- listenWerteIt, listenWerte sind vermutlich ähnlich wie getValue normale Funktionen udn haben auch das selbe Problem.Warum zeigst du nicht per Copy&Paste den wirklichen Code, den du hast? (Natürlich aufs Wesentliche reduziert)
-
Pumuckl hat recht. Da fehlen zwei Semikoli im Header (richtige Plural ?).
Und Einrücken wär nicht schlecht.
-
//dataPool.h namespace dataPool{ std::list<std::string> listenWerte; std::list<std::string>::iterator listenWerteIt; template<typename T> void setValue(double t, int i, T wert); std::string getValue(); } //dataPool.cpp template<typename T> void dataPool::setValue(double t, int i, T wert) { std::stringstream ss; ss<<t<<"\n"<<i<<"\n"<<wert<<"\n"; listenWerte.push_front(ss.str()); } std::string dataPool::getValue(){ listenWerteIt = listenWerte.begin(); std::string wert = *listenWerteIt; return wert; }Das ist der vollständige Code mehr habe ich auch nicht. Ich habe die Sachen genauso wie oben.
-
Ich habe lediglich in module1
#include "dataPool.h"und in Target auch
#include "dataPool.h"
-
Und wie stehen die Beide in Verbindung ?
Du musst schon konkreter werden.
-
Die beiden haben im Prinzip keine Beziehung zueinander. Wie ich schon erwähnt habe, soll mir die namespace als eine Art Zwischenspeicher für alle Objekte dienen.
-
Beobachter01 schrieb:
Das ist der vollständige Code mehr habe ich auch nicht. Ich habe die Sachen genauso wie oben.
Warum nicht gleich.
Also:
- getValue() hatte das beschriebene Problem, das dürfte jetzt nichtmehr auftreten.
- listenWerte und litenWerteIt haben das selbe Problem, nur dass es eben Variablen sind. Die gehören so oder so nicht im header definiert (höchstens deklariert), am Besten garkeine globalen/namespace scope variablen.
- setValue hat das Problem, dass die Template-Definition im Header stehen muss.
alles zusammen sieht mir danach aus, als ob du das Ganze in eine Klasse packen und ein Singleton oder was ähnliches draus machen solltest.
-
Beobachter01 schrieb:
Die beiden haben im Prinzip keine Beziehung zueinander. Wie ich schon erwähnt habe, soll mir die namespace als eine Art Zwischenspeicher für alle Objekte dienen.
- der namespace (Namensraum)
- Ein namespace ist kein Objekt, sondern nur ein Mittel zur Code-Organisation. Du kannst in einem namespace nichts speichern.
-
Soll ich alles in eine Klasse packen und die einzelnen Methoden bzw. Liste auch als static definieren?
Das Ziel soll sein, dass alle Objekte (andere Klassen) in die Liste etwas einfügen und auch entfernen können sollen.
-
Beobachter01 schrieb:
Soll ich alles in eine Klasse packen und die einzelnen Methoden bzw. Liste auch als static definieren?
Wäre eine Möglichkeit. Den Iterator brauchst du sowieso nicht dauerhaft halten, der reicht funktionslokal völlig aus.
-
Stimmt ich könnte den Iterator immer wieder lokal anlegen. Danke dir!
Falls noch Fragen auftauchen sollte komme ich nochmal vorbei
-
Hi nochmals,
ich bekomme jetzt so einen Fehler:
error c2011: 'dataPool' : 'class' type redefinition -> see declaration of dataPoolIch könnte .....! Namespace wurde als eine statische Klasse mit statischen variabeln und Methoden implementiert. Ich habe versucht die Header-Datei wieder in 2 verschiedenen Klassen eingebunden. Wie bekomme ich das hin, dass nur einmal die Klasse definiert wird und alle Zugriff darauf haben?
-
Das klingt so, als hättest du keine Include Guards (mal nach googlen, wenn dir das nichts sagt).