Von einer Klasse, auf eine Funktion einer anderen Klasse zugreifen
-
Hi,
ich weis das die Frage schon mehrfach gestellt wurde, aber leider waren die Antworten für mich nicht ausreichend. Ich bin doch noch Einsteiger, aber sehr Lerngierig.
Wie ich z.B auf eine Funktion aus meiner AppKlasse zugreife, habe ich mittlerweile rausgefunden. Mit
CMyApp* pApp = ((CMyApp*) AfxGetApp()); pApp->OnFileNew();kann ich auf jede Funktion aus meiner AppKlasse zugreifen.
Jetzt habe ich aber folgendes Beispiel.
In meiner zweiten Klasse habe ich diese Funktion
void CzweiterDlg::OnButton2() { m_List.DeleteAllItems(); CStdioFile myFile("data.dat", CFile::modeReadWrite); CString str = ""; while(myFile.ReadString(str))//das File wird zeilenweise Ausgelesen { m_List.InsertItem(0, str,0); } myFile.Close(); }Jetzt möchte ich von meiner ersten Klasse auf die Funktion OnButton2 zugreifen. Dafür habe ich im Header der ersten Klasse, die zweite Klasse includiert.
Nun versuche ich wirklich seit mehreren Tagen, von der Klasse1 auf die Funktion OnButton2 aus meiner zweiten Klasse zuzugreifen.
Ich habe etwas über Pointer gelesen, aber kein ausführliches Beispiel gefunden.Wenn ich es mit
CzweiterDlg* pDlg = ((CzweiterDlg*) AfxGetApp()); pDlg->OnButton2();Versuche, passiert nichts.
Wo ist mein Denkfehler?
Vielen Dank für eure Hilfe
asmodia
-
CzweiterDlg* pDlg = ((CzweiterDlg*) AfxGetApp());
pDlg->OnButton2();CzweiterDlg ist nicht deine App klasse.
kleines bsp wie man so was machen kann:
class Foo1 // klasse 1 { Foo2 *m_pFoo2; // das ist der pointer auf deine 2 klasse public: Foo1() :pFoo2(NULL) // init nicht vergessen { } void SetFoo2Ptr(Foo2 *ptr) { m_pFoo2 = ptr; // merke dir den pointer } void OnIgrendwas() { ASSERT(m_pFoo2!=NULL); // lass es im debuger knallen falls du mal das // SetFoo2Ptr vergessen hast if(m_pFoo2) { m_pFoo2->OnIrgenwas(); // rufe die methode von klasse 2 auf } } } class Foo2 // klasse 2 { public: void OnIgrendwas() { ... } } void doit() { Foo1 foo1; // klasse 1 Foo2 foo2; // klasse 2 foo1.SetFoo2Ptr(&foo2); // setzte dan pointer auf klasse 2 in kasse 1 foo1.OnIrgendwas(); // macht jetzt das was du haben willst }
-
Danke CMatt vielen Dank

Jetzt bringst du Licht ins Dunkel.
Ich hoffe ich verstehe das jetzt richtig,
class Foo1 // klasse 1 { Foo2 *m_pFoo2; // das ist der pointer auf deine 2 klasse public: Foo1() :pFoo2(NULL) // init nicht vergessen { }packe ich in den Header der Klasse1 !? und
void SetFoo2Ptr(Foo2 *ptr) { m_pFoo2 = ptr; // merke dir den pointer } void OnIgrendwas() { ASSERT(m_pFoo2!=NULL); // lass es im debuger knallen falls du mal das // SetFoo2Ptr vergessen hast if(m_pFoo2) { m_pFoo2->OnIrgenwas(); // rufe die methode von klasse 2 auf } }packe ich in die Klasse1!?
Im Header der Klasse 2 mache ich die Funktion OnIgrendwas() public!
soweit habe ich das glaube ich verstanden... bitte korrigiere mich wenn nicht.
Nur wo kommt
void doit() { Foo1 foo1; // klasse 1 Foo2 foo2; // klasse 2 foo1.SetFoo2Ptr(&foo2); // setzte dan pointer auf klasse 2 in kasse 1 foo1.OnIrgendwas(); // macht jetzt das was du haben willst }hin? und wo mache ich doit() bekannt??
In der Klasse1 muss ich doch noch den Header der Klasse 2 einbinden!?
Danke für deine Mühe!
asmodia
-
kommt ganz drauf an.
wo wird den CzweiterDlg erzeugt? in CersterDlg?
-
ja. Ich erzeuge Ihn so
CForm2Dlg* pForm2Dlg; pForm2Dlg = new CForm2Dlg(); pForm2Dlg->Create(IDD_FORM2,this); pForm2Dlg->ShowWindow(SW_SHOWMAXIMIZED); pForm2Dlg->SetDlgItemText(IDC_BLA1 , m_strBla1 ); pForm2Dlg->SetDlgItemText(IDC_BLA2 , m_strBla2 );asmodia
-
dann ist es doch ganz einfach..
CForm1Dlg::func() { CForm2Dlg* pForm2Dlg; pForm2Dlg = new CForm2Dlg(); pForm2Dlg->SetForm1Ptr(this); // <=== setzt den pointer auf klasse 1 pForm2Dlg->Create(IDD_FORM2,this); pForm2Dlg->ShowWindow(SW_SHOWMAXIMIZED); pForm2Dlg->SetDlgItemText(IDC_BLA1 , m_strBla1 ); pForm2Dlg->SetDlgItemText(IDC_BLA2 , m_strBla2 ); }was dann nach fehlt ist ein
#inlcude "Form1Dlg.h"in der Form2Dlg.cpp
und ein
class CForm1Dlg; // wenn du in CForm2Dlg, CForm1Dlg* deklalierst, muss der compiler wissen was das ist ... class CForm2Dlg { ...noch ne anmerkung zu deinem code oben:
CForm2Dlg* pForm2Dlg;
pForm2Dlg = new CForm2Dlg();pForm2Dlg ist eine lokale varaible. Du machst ein new, allokierst also dynmisch speicher. Der code läuft weiter bis zum Funktionsende und springt raus. Wer gibt den speicher jetzt wieder frei? Keiner mehr, da niemand mehr den pointer kennt

-
Danke dir.
Ich versuche das jetzt erst einmal umzusetzen. Und was mach ich wenn ich den Dialog nicht so aufrufe? denn ich habe hier einen angedockten Dialog, und weis nicht wo der aufgerufen wird....
Kannst du dein obiges Beispiel noch vervollständigen?
asmodia