Instanz greift auf Instanz zu -> Zugriffsverletzung [gelöst]
-
Na, indem Du einen weiteren Konstruktor anlegst:
public: // Anwender-Deklarationen __fastcall TForm1(TComponent* Owner); __fastcall TForm1(TComponent* Owner, TForm1* pCallingForm1);Den übergebenen Zeiger musst Du dann in einer Membervariablen speichern um ihn in anderen Methoden nutzen zu können. Im Standardkonstruktor solltest Du diese Membervariabel auf NULL setzen.
-
@Joe_M: Ok, ich muss also den Konstruktor überladen, das ist soweit klar. Allerdings verwirrt mich jetzt, dass du den Konstruktor von Form1 überladen hast. Ist das Absicht oder meintest du Konstruktor von Form2?
Meine grosse Frage ist jetzt, wie ich den Zeiger richtig übergebe - sprich:
void __fastcall TForm1::BtnInstBClick(TObject *Sender) { // ... if(...) { TForm2 *pInstanzB= new TForm2(0); // <==== !!!! // wird zu: TForm2 *pInstanzB= new TForm2(0, &pInstanzA); // ???? pInstanzB->Caption= " Geben Sie Dies und Das ein:"; pInstanzB->BtnTest->Caption= "Test"; pInstanzB->ShowModal(); delete pInstanzB; } // ... }So?
-
Weiß nicht, hab den Überblick verloren.
In welchem Form möchtest Du welche dynamische Forminstanz verwenden?
-
Prinzipiell richtig. Du solltest nur den Adressoperator weglassen. pInstanzA ist doch schon ein Zeiger.
TForm2 *pInstanzB= new TForm2(0, pInstanzA);Damit das Löschen der Zeiger kein Problem mehr ist solltest du irgendwann mal was über Smartpointer lesen. Dann geht auch sowas.
void __fastcall TForm1::BtnInstBClick(TObject *Sender) { // ... if(...) { std::auto_ptr<TForm2> pInstanzB(new TForm2(0, pInstanzA)); pInstanzB->Caption= " Geben Sie Dies und Das ein:"; pInstanzB->BtnTest->Caption= "Test"; pInstanzB->ShowModal(); // delete pInstanzB; // delete kann jetzt entfallen } // ... }
-
Joe_M. schrieb:
Weiß nicht, hab den Überblick verloren.
In welchem Form möchtest Du welche dynamische Forminstanz verwenden?Bei mir ists auch gleich soweit mit dem Überblick

* Ich erzeuge vom Hauptprogramm aus eine dynamische Forminstanz von Form1.
* Von dieser dynamischen Forminstanz (Instanz A) aus erzeuge ich eine dynamische Forminstanz von Form2 (Instanz B).
* Dann möchte ich in einer Methode von Instanz B schreibend auf eine public-Variable von Instanz A zugreifen.
-
Dann brauchst Du in Form2 einen Zeiger auf Form1.
Siehe auch Braunsteins Post. Vermutlich hast Du aber an dieser Stelle die Variable pInstanzA nicht mehr, aber Du willst ja aus dem neuem Form2 auf die (dynamisch erzeugte) Instanz zugreifen, in der Du Dich gerade befindest (richtig?), dann kannst Du dort this übergeben.
-
Joe_M. schrieb:
Dann brauchst Du in Form2 einen Zeiger auf Form1.
Siehe auch Braunsteins Post.Genau.
Joe_M. schrieb:
Vermutlich hast Du aber an dieser Stelle die Variable pInstanzA nicht mehr...
Naja, "nicht mehr" stimmt so nicht - pInstanzA ist eben scheinbar nur in der Klick-Methode des Hauptprogramms gültig, die ich ja mit pInstanzA->ShowModal() temporär verlasse.
Joe_M. schrieb:
... Du willst ja aus dem neuem Form2 auf die (dynamisch erzeugte) Instanz zugreifen, in der Du Dich gerade befindest (richtig?)...
Fast, aktuell befinde ich mich per ShowModal() in Instanz B (dynamische Instanz von Form2) und möchte auf Instanz A (vorher erstellte dynamische Instanz von Form1) zugreifen, welche ebenfalls aktuell noch mit ShowModal() angezeigt wird. Das geht aber einfach mit der Zeile in Instanz B
pInstanzA->publicVariable= Edit1->Text;nicht (Zugriffsverletzung).
Schema: Hauptprogramm
Klick
Erzeugen pInstanzA(Form1)
ShowModal()
Button-Klick auf pInstanzA
Erzeugen pInstanzB(Form2)
ShowModal()
Button-Klick auf pInstanzB
ändern von Public-Variable von pInstanzAJoe_M. schrieb:
...dann kannst Du dort this übergeben.
Wo jetzt?
Ich glaube ich habs schon halbwegs kapiert, Instanz B kennt halt Instanz A nicht, und deswegen brauch ich nen Zeiger auf Instanz A, den ich beim Erzeugen von Instanz B an den (überladenen) Konstruktor übergeben kann. Damit ich innerhalb Instanz B mit dem Zeiger arbeiten kann, muss ich den übergebenen Zeiger in eine Member-Variable von Instanz B packen und zwar im Konstruktor. Und da ist momentan noch mein Problem: Wie muss die Member-Variable aussehen, in die ich den Zeiger "packe"? Ist das eine public-Variable von Instanz B? Ist es ebenfalls ein Zeiger? Wenn ja, welchen Typ muss dieser "Member-Zeiger" haben? Und was "packe" ich in den hinein? Die Adresse? Ich raffs nicht...
Hat mal einer nen Codeschnipsel bitte, wie das "Packen des übergebenen Zeigers in eine Member-Variable" im überladenen Konstruktor aussehen muss?Edit: Rechtschreibung

-
Kolumbus schrieb:
Wie muss die Member-Variable aussehen, in die ich den Zeiger "packe"? Ist das eine public-Variable von Instanz B? Ist es ebenfalls ein Zeiger? Wenn ja, welchen Typ muss dieser "Member-Zeiger" haben? Und was "packe" ich den hinein? Die Adresse? Ich raffs nicht...
Es sollte eine membervariable im private-Bereich von TForm2 sein. Der Typ wäre dann Zeiger auf TForm1.
// .h: class TForm2 : public TForm { __published: // ... private: TForm1* pForm1; public: __fastcall TForm2(TComponent* Owner, TForm1* InstanzA); }; // .cpp - Konstruktor: __fastcall TForm2::TForm2(TComponent* Owner, TForm1* InstanzA) : TForm(Owner), pForm1(InstanzA) { }
-
Braunstein schrieb:
Es sollte eine membervariable im private-Bereich von TForm2 sein. Der Typ wäre dann Zeiger auf TForm1.
Schön, dann bin ich ja doch nich so doof - so hab ich mir das gedacht.
Braunstein schrieb:
// .cpp - Konstruktor: __fastcall TForm2::TForm2(TComponent* Owner, TForm1* InstanzA) : TForm(Owner), pForm1(InstanzA) { }Das hat mir gefehlt, Danke - wird sofort getestet!

-
__fastcall TForm2(TComponent* Owner, TForm1*/**/ pInstanzA);[C++Fehler] 2.h(27): ) expected.
Hilfe schrieb:
Am Ende einer Parameterliste wird eine abschließende rechte Klammer erwartet.
Is doch eine da???

Edit: da wo ich die Kommentar-Zeichen gemacht habe, steht der Cursor bei der Fehlermeldung, falls das was zu bedeuten hat!?!
-
Ich schätze mal er kennt TForm1 nicht. Mach einfach mal eine Forwarddeklaration oben in der Headerdatei.
class TForm1;
-
Na, haste denn den header von TForm1 in den header von TForm2 eingebunden?
-
Um den nächste Frage zu überspringen: Haste Include-Guards verwendet?
-
Den Header von Form1 habe ich in 1.cpp eingebunden... reicht das nicht?
Und include-Guards hab ich standardmäßig drin in allen Headern, ja - aber is ja nicht relevant, weil #include "1.h" in 2.cpp steht.
-
Aber auch in 2.h?
-
Nein das reicht nicht. TForm1 muss auch im header bekannt sein wegen der Deklaration deines Konstruktors. Ich sagte ja schon, eine Forwarddeklaration von TForm1 reicht da.
Include-Guards werden beim BCB sowieso standardmäßig erzeugt.
-
Ok, Danke für den Hinweis. Jetzt kann ich auch problems einen Zeiger vom Typ Form1 als private-Variable in 2.h deklarieren...
Und was soll ich sagen Leute, es wäre zwar viel einfacher gewesen die Forms beim Programmstart zu erzeugen, aber wer wills schon einfach? Es funktioniert jetzt, also special thanks to: Braunstein, Joe_M und witte! Ihr seid Spitze

Schön, dass ihr nicht die Nerven verliert wenn man sich doof anstellt!
Was ich Alles gelernt habe:* ich habe zum 1. Mal einen Konstruktor überladen
* ich habe zum 1. Mal einen Zeiger an einen Konstruktor übergeben
* ich habe zum 1. Mal Daten zwischen 2 dynamischen Form-Instanzen ausgetauscht
* ich weiß jetzt, dass ich auch im Header ein #include setzen muss, wenn ich dort Objekte eines anderen Forms zugänglich machen willDas nur Mal so auf die Schnelle... Ich poste dann gleich mal noch das Ergebnis als Codeschnipsel!
-
Wenn du den Include wirklich im Header gestzt hast, dann nimm ihn doch probeweise wieder raus und befolge meinen Hinweis mit der Forwarddeklaration. Jetzt mag das für dich vielleicht noch keinen Unterschied machen aber glaube mir, bei größeren Projekten macht sich das bemerkbar.
1. Du verringerst Abhängigkeiten
2. Du erhöhst die Compilegeschwindigkeit
-
Ok, ich belese mich gleich mal dazu und mache das dann - habe ich gar nicht mehr dran gedacht.
Edit: Das ist gut - mache ich jetzt öfter - Dankeschön!
-
Noch eine wichtige Frage zu der Problematik:
Wäre es nicht geschickter hier mit einer Referenz zu arbeiten anstelle eines Zeigers???