Funktion aus anderer Klasse aufrufen
-
Hallo zusammen,
ich steh mal wieder auf dem Schlauch und möchte euch um Hilfe bitten.Mein Programm besteht aus mehreren Klassen. Aus Klasse A heraus rufe ich eine Funktion in Klasse B auf. Kein Problem. Rufe ich aber aus der Funktion in Klasse B eine Funktion aus Klasse C auf, erhalte ich folgende Fehlermeldung:
Unbehandelte Ausnahme bei 0x0041aef6 in Msbm.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x000000cc.
Mein Programm sieht an den entscheidendem Stellen so aus:
//MView.h class CExp; public: CExp* m_pExp; //MView.cpp #include "MView.h" #include "Exp.h" CMView::CMView(CWnd* pParent /*=NULL*/) : CDialog(CMView::IDD, pParent) { m_pExp = NULL; } int CMView::OnExpLoadA(EXPDATA* lpExpData) { //folgender Aufruf erzeugt die Fehlermeldung if(m_pExp->ExpGetA(lpExpData) != NULL) { } } //Exp.h public: CExp* m_pExp; AS* ExpGetA(EXPDATA* lpExpData); //Exp.cpp #include "Exp.h" #include "MView.h" AS* CExp::ExpGetA(EXPDATA* lpExpData) //diese Funktion sollte er aufrufen { }
Ich hoffe, dass ich nichts wichtiges vergessen habe.
Wie gesagt
OnExpLoadA(EXPDATA* lpExpData)
wird aus einer anderen Klasse heraus aufgerufen (die Einbíndung der Headerdatei und des Zeigers sieht genauso aus) und funktioniert.
Geht es prinzipiell nicht Funktionen aus einer dritten Klasse aufzurufen, oder mache ich da was ganz falsch? Hat einer von euch eine Idee??
Bitte helft mir. Ich kann doch nicht allen Code in eine Endlos-Klasse schreiben.
Schon mal Danke für eure Mühe, meine Frage zu verstehen und vielleicht eine Lösung zu finden.
Triple?
-
m_pExp = NULL;
Ist der Zeiger an der Stelle des Aufrufs vielleicht noch null?
Übrigens: Deine Typ- und Variablennamen sind absolut grausam.
-
Danke für deine Hilfe.
Jupp, der Zeiger ist leer. Woher bezieht er überhaupt seinen Wert???Meine Typ-und Variablennamen habe ich hier stark zusammengekürzt. Ne, so kann ich auch auf lange Sicht nicht arbeiten.
-
Entweder existiert das Objekt, dann bekommst Du den Zeiger aus dem Kontext. Oder Du bist selbst verantwortlich so ein Objekt zu erzeugen.
-
Ich habe jetzt in der Funktion
OnExpLoadA(EXPDATA* lpExpData) { CExperiment* m_pExp; m_pExp = NULL; if(m_pExp->ExperimentGetAParam(lpExpData) != NULL) { } }
Zeigerdeklaration und Initialisierung noch mal angegeben und siehe da es funktioniert. Aber das kann doch nicht die saubere Lösung sein, oder???
-
Auf alle Fälle ein großes Dankeschön für eure Hilfe. Ihr habt mir mal wieder sehr geholfen.
Triple?
-
Triple? schrieb:
Ich habe jetzt in der Funktion
OnExpLoadA(EXPDATA* lpExpData) { CExperiment* m_pExp; m_pExp = NULL; if(m_pExp->ExperimentGetAParam(lpExpData) != NULL) { } }
Zeigerdeklaration und Initialisierung noch mal angegeben und siehe da es funktioniert. Aber das kann doch nicht die saubere Lösung sein, oder???
Nöö! 100% falsch und undefiniert. pExp ist NULL. Das ganze wäre nur gültig, wenn ExperimentGetAParam statisch ist!
-
Aber wenn ExperimentGetAParam() statisch ist dann bräuchte er auch net den Umstand über einen Null-Zeiger zuzugreifen, dann würde doch einfach
CExp::ExpGetA(lpExpData)
genügen. Doch so wie er es geschrieben hat müsste das eigentlich gegen die Wand laufen weil Zugriff auf einen Null-Zeiger.
Wenn dann würde ich ja sagen
OnExpLoadA(EXPDATA* lpExpData) { CExperiment m_pExp; if(m_pExp.ExperimentGetAParam(lpExpData) != NULL) { } }
denn das ganze als Zeiger macht keinen Sinn denn sobald der Scope der Funktion verlassen wird ist der Zeiger eh weg und dann liegt ein Totes Objekt da.
Oder Wenn dann doch der Zeiger Benötigt wird dann das Objekt mit new erstellen.
So nun hab ich meinen Senf dazu gegeben, vielleicht Hilft es etwas
-
Hallo CTec$,
vielen Dank für deinen "Senf".Hab jetzt deinen Tip ausprobiert und er funktioniert.
Mir gefällt zwar immer noch nicht, dass ich die Variable nun in jeder Funktion (die sie braucht) neu deklarieren muss, aber was soll's. Ist jedenfalls besser als immer wieder den Zeiger kurz vor der Verwendung zu löschen.Vielen Dank dir und auch Martin Richter.
-
Triple? schrieb:
Ist jedenfalls besser als immer wieder den Zeiger kurz vor der Verwendung zu löschen.
Das ist sowas von falsch, dass es schon wieder lustig ist
Du kannst natürlich ein Objekt über Methodengrenzen hinweg verwenden.
Aber hier eine Erklärung zu starten rentiert sich kaum. Hast Du ein gutes Grundlagenbuch?