Zugriff auf eine Methode der Erzeugungsklasse?
-
Guten Tag!
Ich hab mich jetzt hier ein wenig schlau gemacht über mein Problem, aber so richtig weiß ich immer noch nicht wie ich vorgehen soll.Ich habe eine Hauptklasse mit Methoden. Aus dieser Hauptklasse erzeuge ich eine weitere Klasse. Nun möchte ich aber auch die Möglichkeit haben aus der gerade eben erzeugten Klasse auf die Methoden der Hauptklasse zuzugreifen.
Wie soll ich das realisieren mit einer Referenzübergabe oder mit einem Zeiger?
*this als Übergabeparameter gleich beim Erzeugen der neuen Klasse?
Ich bin leider noch ein Newbie, also nicht böse sein, wenn die Frage dumm sein sollte.
Erschwerend kommt noch hinzu, dass die Klassen natürlich in getrennte Dateien stehen. Also ich hab cpp und h Dateien. Ich muß also ein wenig mehr berücksichtigen.
Ich zeig Euch mal ein kleines Beispiel:
main_window.h :
#include "toplevel_w.h" class Main_window { public: // Konstruktor Main_window(); // Destruktor ~Main_window(); void fuelleTextfeld(string); // Funktion, das ein Textarea-field im // Main_window mit übergebenen Text füllt private: Toplevel_w m_ptoplevelw; // neues Objekt der Klasse Toplevel_w // Muß ich hier schon etwas modifizieren???
main_window.cpp
#include "main_window.h" //Konstruktor Main_window::Main_window() { } //Destruktor Main_window::~Main_window() { } void Main_window::fuelleTextfeld(string text) { this->Statusbox->insert(text); }
toplevel_w.h
class Toplevel_w() // <- Muß ich hier etwas modifizieren, wenn mein Problem // gelöst werden soll? { public: // Konstruktor Toplevel_w(); // Destruktor ~Toplevel_w(); void drueckeKnopf(); // Funktion, die bei einem Knopfdruck im // Toplevelwindow aufgerufen wird }
toplevel_w.cpp
#include "toplevel_w.h" // Konstruktor Toplevel_w::Toplevel_w() { } // Destruktor Toplevel_w::~Toplevel_w() { } void Toplevel_w::drueckeKnopf() { string input = lineEdit->text(); // Methode zum Auslesen eines // Entry-Feldes // so und nun das Problem: ???.fuelleTextfeld(input); // <- Wie greif ich auf diese Methode zu? }
Vielleicht kann hier ja jemand mir ein wenig weiterhelfen, oder sogar schnell mein Beispiel so modifizieren, dass es klappen könnte.
Würde mich natürlcih sehr freuen.Gruß skontox
-
Hi,
wenn du das wirklich so haben willst - und ich bezweifle irgendwie das das wirklich Sinn hat (vielleicht solltest du dein Design mal überdenken), dann würde ich dem Konstruktor der Klasse Toplevel_w eine Referenz auf die Hauptklasse Main_Window übergeben und das in einer privaten Membervariablen speichern.
//... // Toplevel_w hat eine private Membervariable m_mainWnd private: Main_Window& m_mainWnd; // ... // und der Konstruktor: Toplevel_w( Main_Window& mainWnd ) { m_mainWnd = mainWnd; }
Jetzt kannst du über diese Membervariable immer auf die Klasse Main_Window zugreifen. Natürlich musst du jetzt beim Deklarieren einer Variable dem Konstruktor auch etwas übergeben!!!
Ich hoffe, das hat ein bisschen geholfen...
Mfg, smasher1985
-
Danke für die Antwort!
Aber leider haut das bei mir nicht hin.Ich bekomme eine Fehlermeldung:
toplevel_w.h:58: error: syntax error before '&' token.
Muß ich das der Klasse nicht irgendwie bekanntgeben, was "Main_window" überhaupt ist?
Also includieren oder so?
Kannst du mir das mal anhand meines Beispiels zeigen. Sprich mal etwas modififieren.
Das wäre sehr nett.
Kann ich nicht auch beim Erzeugen der Toplevel_w Klasse in der Datei main_window.h gleich die Referenz auf die Main_window-Klasse übergeben?
Gruß skontox
-
Ein interessantes Thema und gar nicht so einfach, wie man denkt. Ich stolpere auch immer wieder über das Problem: Wo krieg ich meinen Zeiger auf ein Object her?
Wenn man das Objectmodell selber programmiert, hab ich mir das eigentlich so angewöhnt:#include "parent.h" class child { child(){}; ~child(){}; private: parent* m_parent; public: set_parent(parent* p){m_parent = p;}; parent* get_parent(){return m_parent;}; } #include"child.h" class parent { parent(){ child* m_child; m_child = new child; m_child->set_parent(this); } ~parent(){...} private: child* m_child; }
Leider gibts hier ganz schnell einen Zirkelbezug. Parent includiert child und child includiert parent. Ich hab auch schon mal mit friend rumexperimentiert. Vielleicht kann ja dazu noch jemand seinen Kommentar schreiben ?!?
Noch schlimmer wirds, wenn man ne Bibliothek benutzt uns sich nicht sicher ist, wie man nen Zeiger herkriegt. Zum Bleistift:
CFrameWnd* frame = (CFrameWnd*)AfxGetMainWnd(); myDocument* myDoc = (myDocument*)frame->GetActiveDocument();
myDocument is natürlich von CDocument abgeleitet und das wieder von CWnd, CFrameWnd).
Damit kann man sich wochenlang ziemlich erfolglos beschäftigen und man kommt nix weiter.
-
mit forward declarations im header arbeiten.
implementation in der cpp datei und auch nur da den header einbinden. da gibts keinen Zirkelbezug.
-
Ich hab das hier mit Hilfe eines Kumpels modifiziert:
main_window.h :
#include "toplevel_w.h" class Main_window { public: // Konstruktor Main_window(); // Destruktor ~Main_window(); void fuelleTextfeld(string); // Funktion, das ein Textarea-field im // Main_window mit übergebenen Text füllt private: Toplevel_w m_ptoplevelw; // neues Objekt der Klasse Toplevel_w // Muß ich hier schon etwas modifizieren???
main_window.cpp
#include "main_window.h" //Konstruktor Main_window::Main_window():m_ptoplevelw(this) //oder *this { } //Destruktor Main_window::~Main_window() { } void Main_window::fuelleTextfeld(string text) { this->Statusbox->insert(text); }
toplevel_w.h
#include "main_window.h" class Toplevel_w() // <- Muß ich hier etwas modifizieren, wenn mein Problem // gelöst werden soll? { public: // Konstruktor Toplevel_w(Main_window); // Destruktor ~Toplevel_w(); void drueckeKnopf(); // Funktion, die bei einem Knopfdruck im // Toplevelwindow aufgerufen wird private: Main_window m_pmw; }
toplevel_w.cpp
#include "toplevel_w.h" // Konstruktor Toplevel_w::Toplevel_w(Main_window &tmp) { m_pmw=tmp; } // Destruktor Toplevel_w::~Toplevel_w() { } void Toplevel_w::drueckeKnopf() { string input = lineEdit->text(); // Methode zum Auslesen eines // Entry-Feldes // so und nun das Problem: m_pmw.fuelleTextfeld(input); // <- Modifiziert }
So könnte es klappen, muß ich gleich mal ausprobieren!
Großen Dank an Snake!
Gruß skontox
-
Alles schön und gut, aber irgendwie klappt das nicht!
Gruß skontox
-
Endlich haut es hin!
Dank der Beiträge von electron und Unregistrierter (forward declaration) hab ich ein neues Beispiel gecoded das jetzt auch läuft und das macht was ich will.
Da es wahrscheinlich auch andere Newbies interessieren könnte, zeige ich das neue Beispiel nochmal:main.cpp
#include "mainw.h" #include "topw.h" #include <iostream> using namespace std; int main() { MainW mw; // Neue Instanz von MainW wird erzeugt return 0; }
mainw.h
#ifndef __MAINW__H__ #define __MAINW__H__ #include <string> #include <iostream> using namespace std; class TopW; // hier ist die "forward declaration" class MainW { public: MainW(); // Konstruktor ~MainW(); // Destruktor void who_are_you(string); // Methode zur Ausgabe von einem übergebenen // String private: TopW* m_tw; // Private Member Variable }; #endif
mainw.cpp
#include "mainw.h" #include "topw.h" MainW::MainW() { m_tw = new TopW; // Neue Instanz von TopW wird erzeugt m_tw->set_parent(this); // Methode "set_parent()" der Klasse TopW // wird aufgerfufen und bekommt ein // This-Objekt (Die jetzige Instanz // dieser Klasse) übergeben. } MainW::~MainW() { } void MainW::who_are_you(string text) { cout << text << endl; // hier wird der übergebene String ausgegeben }
topw.h
#ifndef __TOPW__H__ #define __TOPW__H__ #include <string> using namespace std; class MainW; // Hier ist die "forward declaration" class TopW { public: TopW(); // Konstruktor ~TopW(); // Destruktor void set_parent(MainW*); // Diese Methode erwartet ein Objekt vom Typ MainW void call(); // Diese Methode ruft die Methode // "who_are_you(string)" der Klassse MainW auf private: MainW* m_mw; // Private Member Variable }; #endif
topw.cpp
#include "topw.h" #include "mainw.h" TopW::TopW() { } TopW::~TopW() { } void TopW::set_parent(MainW* p) { m_mw = p; this->call(); // Methode call() dieses TopW-Objektes wird aufgerufen } void TopW::call() { string var="Nielsi"; // Variable vom Typ String wird deklariert und // mit "Niels" initialisiert m_mw->who_are_you(var); // Aufruf der Methode aus Klasse MainW, // die wir übergeben bekommen haben }
Ich hoff ich konnte damit auch anderen Newbies weiterhelfen.
Gruß skontox
-
Ich habs mal überflogen und man sollte vielleicht noch anmerken, dass die Namen der Include-Guards ungültig sind (Faustregel: Finger weg von allem, was mit einem _ anfängt, das ist für die Implementierung da). "using namespace" hat in Headern nichts zu suchen, weil du damit jedem Benutzer des Headers den namespace auch aufzwingst. Außerdem wird das mit new angelegte TopW nirgends freigegeben. Ich würde hier lieber topw.h includen und das Objekt direkt, nicht über einen Zeiger als Member anlegen. Solange sich die Header nicht gegenseitig includen, ist doch alles in Butter. Die Pointer-Variante ist so jedenfalls mehrfach buggy.
-
Besten Dank operator void!
Finde ich gut, dass Du mir den Hinweis gegeben hast!
Gruß skontox
-
Auf Anraten von operator void habe ich das Beispiel nochmal modifiziert.
Ich hoffe ich habe alles berücksichtig was mir operator void zugetragen hat:
main.cpp
#include "mainw.h" #include <iostream> using namespace std; int main() { MainW mw; // Neue Instanz von MainW wird erzeugt return 0; }
mainw.h
#ifndef MAINW__H__ #define MAINW__H__ #include <string> #include <iostream> #include "topw.h" class MainW { public: MainW(); // Konstruktor ~MainW(); // Destruktor void who_are_you(std::string); // Methode zur Ausgabe von einem // übergebenen String private: TopW m_tw; // Private Member Variable }; #endif
mainw.cpp
#include "mainw.h" using namespace std; MainW::MainW() { m_tw.set_parent(this); // Methode set_parent der Klasse TopW wird // aufgerfufen und bekommt ein This-Objekt // (Die jetzige Instanz dieser Klasse) // übergeben. } MainW::~MainW() { } void MainW::who_are_you(string text) { cout << text << endl; // hier wird der übergebene String ausgegeben }
topw.h
#ifndef TOPW__H__ #define TOPW__H__ #include <string> class MainW; // Here is the forward declaration class TopW { public: TopW(); // Konstruktor ~TopW(); // Destruktor void set_parent(MainW*); // Diese Methode erwartet ein Objekt vom Typ MainW void call(); // Diese Methode ruft die Methode //"who_are_you(string)" der Klassse MainW auf private: MainW* m_mw; // Private Member Variable }; #endif
topw.cpp
#include "topw.h" #include "mainw.h" using namespace std; TopW::TopW() { } TopW::~TopW() { } void TopW::set_parent(MainW* p) { m_mw = p; this->call(); // Methode call() dieses TopW-Objektes wird aufgerufen } void TopW::call() { string var="Nielsi"; // Variable vom Typ String wird deklariert // und mit "Niels" initialisiert m_mw->who_are_you(var); // Aufruf der Methode aus Klasse MainW, // die wir übergeben bekommen haben }
So, ich hoffe das war alles!
Gruß skontox