Namespace in Klasse
-
Hi,
ich würde gern einen Namespace innerhalb einer Klasse definieren, also quasi so:class A { //... namespace d { //... }; };
Wenn ich jetzt versuche, das zu kompilieren, kommt so ein Fehler:
error: expected unqualified-id before "namespace"Wozu das ganze? Ich möchte in meiner Klasse Funktionen so definieren, dass der User sie selbst setzten kann, mittels Funktionszeigern. Die Klasse soll aber auch Standard-Funktionen dafür haben, falls der User sie nicht setzen will. Und die will ich in dem Namespace unterbringen.
Wenn jemand eine Idee hat, wie ich meinen Namespace doch definiert bekomme oder wie ich das ganz anders lösen könnte, wäre ich sehr dankbar.
Gruß,
Morph
-
Du kannst diese Methoden in ein Struct packen
class UserDriven { public: UserDriven(); ~UserDriven(); struct std { void Funktion1(); int Funktion2(); } }; UserDriven froop(); froop.std.Funktion1();
-
hehejo schrieb:
Du kannst diese Methoden in ein Struct packen
class UserDriven { public: UserDriven(); ~UserDriven(); struct std { void Funktion1(); int Funktion2(); } }; UserDriven froop(); froop.std.Funktion1();
Das funktioniert so leider nicht. Zum einen gibt es kein Member std, denn das ist nur ein nested Type, aber selbst wenn da
struct { ... } std;
stehen würde, hilft das nicht weiter, denn dann sind das Methoden von std, und nicht von UserDriven/A, und die könnten auf nichts zugreifen (okay, std könnte mit einem Zeiger auf UserDriven initialisiert werden, aber sie wären auch nicht Method-Pointer-Kompatibel mit jenen in UserDriven resp. A)
@morph01: Zum eigentlichen Problem: Zunächst einmal wissen wir leider nicht, ob es um statische Methoden geht oder nicht. Wenn sie nicht statisch sein sollen, und dennoch Methoden von A, hilft die Lösung wie gesagt auch in Variation nicht weiter. Und es ist auch nicht möglich, Namespaces innerhalb von Klassen zu deklarieren.
Ohne nähere Infos über die Art der "Funktionen" um deren Pointer es hier gehen soll, ist es schwer zu helfen. Also bitte noch etwas näher spezifizieren: statische Methoden oder nicht? Brauchen sie Zugriff auf nicht statische Member? Was genau soll passieren?
-
Die Methoden sollen schon mit (nicht statischen) Membern der Klasse arbeiten, deshalb also erstmal nicht statisch.
Es wäre aber auch möglich, den this-Zeiger an die Funktion zu übergeben, dann könnte man sie denke ich statisch machen.
Die Methode soll aus dem entsprechenden Objekt und einem anderen Objekt ein neues Objekt erstellen (also so, wie das z.B. der operator+ macht)Hilft das?
-
Wenn ich dein Problem richtig verstanden habe, dann springt mir eigentlichj sofort eine logische Lösung ins Auge: Mach UserDriven zu einer polymorphen Basisklasse. Die Funktionen, die der Nutzer "selbst setzen" kann sind dann virtuelle Elementfunktionen von UserDriven. Die Standard-Implementation definierst du in der Basisklasse. Wenn ein Benutzer nicht die Standardimplementierung verwenden möchte, leitet er von UserDriven ab und überschreibt die jeweilige Methode.
-
Das halte ich für ne ziemlich gute Idee, werd ich gleich mal ausprobiern.
Danke !
Morph
-
Hmm, geht doch nicht so einfach...
Ich möchte meine Klasse(nennen wir sie mal "A") nämlich noch in anderen Klasen benutzen("B").
Wenn der Benutzer jetzt Klasse "A" ableitet, hat die abgleitete Klasse "X" logischerweise einen anderen Namen und "B" benutzt weiterhin "A", statt "X" mit den neuen Methoden. Deshalb hatte ich eigentlich die Idee mit den Zeigern, ich wäre dann unabhängig von Namen.Hat da jemand eine idee?
Morph
-
kommt auf dein design an. wie wärs mit templates?
struct A { virtual void Irendwas() { std::cout << "class a" << std::endl; } }; struct X : public A { virtual void Irendwas() { std::cout << "class x" << std::endl; } }; template< class Use_> class B : public Use_ { }; B<X> bx; // hier werden die methoden von x benutzt B<A> ba; // hier von a
-
eine andere Möglichkeit wäre, in B bloß einen zeiger vom Typ a zu haben, dann kann man dem Konstruktor ein beliebiges Objekt vom Typ A (oder abgeleitet) übergeben:
class A { virtual void Irendwas() { std::cout << "class a" << std::endl; } }; class X : public A { virtual void Irendwas() { std::cout << "class x" << std::endl; } }; class B { private: A * _myA; public: B(A * myA) : _myA(myA){}; ~B() { delete _myA; } } int main() { B einB_mitA(new A()); B einB_mitX(new X()); }
Bei Templates stößt mir immer auf, dass in dem Fall nur sehr spezielle Template-Parameter gegeben werden dürfen und man da eigentlich keinen Einfluss drauf hat...
-
pumuckl schrieb:
eine andere Möglichkeit wäre, in B bloß einen zeiger vom Typ a zu haben, dann kann man dem Konstruktor ein beliebiges Objekt vom Typ A (oder abgeleitet) übergeben
Hmm, das kapier ich jetzt nicht so ganz... Wenn man einen Zeiger vom Typ A hat und Irendwas() in A virtual ist, wird doch auch A::Irendwas() benutzt, weil es ja über einen Zeiger vom Typ A angesprochen wird.
Oder hab ich da was falsch verstanden?
-
Das virtual sagt ja aus, daß nicht unbedingt die Methode aus A benutzt wird, sondern wenn du eine Klasse X von A ableitest und den Zeiger an B übergibst, dann wird die entsprechende Methode aus X aufgerufen (vorausgesetzt, sie ist definiert worden, ansonsten wird dann doch auf die Methode von A zugegriffen).
In dem Beispiel von "pumuckl" fehlte nur noch der Aufruf der virtuellen Methode, z.B. direkt im Konstruktor von B:
B(A * myA) : _myA(myA) { myA->Irendwas(); };
Bei Aufruf von "B einB_mitX(new X())" wird nun die Methode "X::Irendwas" aufgerufen.
Schau dir noch mal die Erklärung zu virtuellen Methoden an, falls du es nicht verstanden hast.
-
Alles klar, hubs kapiert...
Danke für eure Ideen, werde vermutlich die Version von pumuckl benutzen, weil ich ziemlich viele verschachtelte Klassen hab und man dann alles in einem Konstruktor angeben kann, also Z.B.
kurt = new D(new A_base, new B_ext, new C_base);
statt
kurt = new D <C_base <B_ext <A_base> > >;
Vielen Dank an alle,
Morph