Anfänger: Array aus Strings (System::String)



  • 1. Frage: Um beide Elemente (Deklaration in der h und Funktionsdefinition in der cpp) habe ich eine Namespace-Klammer mit gleichem Bezeichner gesetzt. Diesen nutze ich auch zum Aufruf. Es funktioniert, aber ist das richtig/okay/üblich so?

    Das kannst Du so machen. Ich qualifiziere meistens voll, auch in den CPP Files.

    2. Frage: Vom Eventhandler in Form1.h aus gesehen ist mein Objekt, welches ich in der *.cpp erzeugt habe, unsichtbar. Wieso? Lässt sich ein Objekt auch so erzeugen, daß es global sichtbar ist?

    Ja (allerdings nur für natives C++), das wären dann globale Variablen, welche aber ihre Nachteile haben und vermieden werden sollten.

    Zwei Lösungsvorschläge:
    1. Instanziere doch dein Objekt erst in Form1. Es ist dann ein Member der Form1 und Du kannst innerhalb der Form1 bequem darauf zugreifen.
    2. Du kannst es ausserhalb der Form1 erzeugen und machst das Objekt auf irgendeine Art dem Form1 Objekt bekannt. Z.B. indem Du es via Konstruktur übergibst oder einer Methode (bzw. Property) von Form1. Natürlich nur eine Referenz / Pointer.

    3. Frage: Um innerhalb von form1.h ein Objekt erzeugen zu können, musste ich erneut die eigene Klassen-Deklaration .h einbinden, die auch schon in die projekt.cpp eingebunden hatte. Es funktioniert zwar - aber ist das richtig/okay/üblich so?

    Ja, das ist gut so. Manchmal tuts auch eine Vorwärtsdeklaration im Header File und das Include wird erst in der Source Datei gemacht. Lies darüber einfach mal.

    $imon



  • Danke für die Antwort, die etwas Licht ins Dunkel bringt.

    theta schrieb:

    Ja (allerdings nur für natives C++), das wären dann globale Variablen, welche aber ihre Nachteile haben und vermieden werden sollten.

    Ich verstehe, daß diese Empfehlung Sinn macht. Ich fragte hauptsächlich deswegen, um die Zusammenhänge zu verstehen.

    theta schrieb:

    2. Du kannst es ausserhalb der Form1 erzeugen und machst das Objekt auf irgendeine Art dem Form1 Objekt bekannt. Z.B. indem Du es via Konstruktur übergibst oder einer Methode (bzw. Property) von Form1. Natürlich nur eine Referenz / Pointer.

    Okay, hier möchte ich mal nachhaken, ob ich es richtig verstanden habe:

    Zu Möglichkeit 1: Wenn ich ausserhalb von form1.h ein Objekt erzeuge, könnte ich also einen Pointer auf dieses Objekt dem Code in form1.h zukommen lassen, über den Konstruktor von form1? Also beim Erzeugen von Form1?

    Also hier hin?

    Application::Run(gcnew Form1(Pointer_auf_Objekt));
    

    Und hier hin?

    Form1(Pointer_auf_Objekt)
    		{
    			InitializeComponent();
    
    			// UND den übergebenen Pointer HIER dann irgendeiner privaten Pointer-Variablen innerhalb von Form1 zuweisen?
    			//
    			//
    		}
    

    Zur Möglichkeit 2, meinst Du damit: Ich könnte also eine Funktion in der Klasse "form" programmieren, die einen Pointer für dieses Objekt annimmt, und die ich zur Übergabe von ausserhalb aufrufen kann? (beispielsweise von einer aus "form1" dort aufgerufenen "form2", die an "form1" auf diese Art Rückgabewerte liefert, bevor sich form2 beim Schließen selbst plattmacht?)

    Neue Frage 1: Wie darf ich mir das vorstellen, Objekte (z.B. ein std::string) können Member von anderen Objekten (z.B. form1) sein? Kann man Objekte selbst einem anderen Objekt übergeben, d.h. "die sind dann dort und nur dort", oder eben nur einen Pointer auf ein Objekt, und im Prinzip könnten alle Objekte (z.B. auch form2) auf dieses Objekte zugreifen, wenn sie nur den passenden Pointer darauf irgendwoher bekommen?

    Neue Frage 2: Jochen Kalmbach schreibt ja "Bitte verschiebe die *Implementierung* der Methoden (zu Member-Funktion sagt man Methoden), in die CPP-Datei (die Du auch noch zuerst anlegen musst)."

    Welche Methoden meint er? form1 hat (soweit ich das im Code sehe/verstehe) standardmässig keine Methoden, die in der form1.h implementiert wären, ausser dessen Konstruktor, Destruktor und die Funktionen, die von den Eventhandlern aus aufgerufen werden. Meint er letztere?

    Neue Frage 3:

    Dieser Codeschnipsel hier (automatisch vom FormDesigner generiert) scheint ja ein Objekt "Eventhandler" für einen Knopfdruck zu erzeugen:

    this->evaopenbutton->Click += gcnew System::EventHandler(this, &Form1::evaopenbutton_Click);
    

    Ich verstehe auch, daß der Konstruktor dieses Eventhandlers offenbar übergeben bekommt, welche Funktion er nachher aufrufen soll. Wie könnte man umgangssprachlich ausdrücken, was davor steht (also "this->evaopenbutton->Click += "), und was diese Zeile also insgesamt bewirkt?

    (Meine Theorie: Die Adresse dieses neu erzeugten Eventhandlers landet im Attribut "Click" des Objektes "evaopenbutton". Stimmt das so? Heisst das, daß gcnew immer einen Pointer auf das gerade frisch erzeugte Objekt als Funktionswert zurückgibt?)



  • maugli schrieb:

    Zu Möglichkeit 1: Wenn ich ausserhalb von form1.h ein Objekt erzeuge, könnte ich also einen Pointer auf dieses Objekt dem Code in form1.h zukommen lassen, über den Konstruktor von form1? Also beim Erzeugen von Form1?

    und

    maugli schrieb:

    // UND den übergebenen Pointer HIER dann irgendeiner privaten Pointer-Variablen innerhalb von Form1 zuweisen?

    Ja, genau so meinte ich das.

    maugli schrieb:

    Zur Möglichkeit 2, meinst Du damit: Ich könnte also eine Funktion in der Klasse "form" programmieren, die einen Pointer für dieses Objekt annimmt, und die ich zur Übergabe von ausserhalb aufrufen kann? (beispielsweise von einer aus "form1" dort aufgerufenen "form2", die an "form1" auf diese Art Rückgabewerte liefert, bevor sich form2 beim Schließen selbst plattmacht?)

    Das meinte ich so:

    ref class MyObject;
    
    ref class Form1 : Form
    {
    public:
       void SetMyObject(MyObject^ myObject)
       {
          // ...
       }
    };
    

    Einfach eine Methode anstelle des Konstruktors. Dasselbe mit Properties. Der Rest deines Zitates ist etwas wirr...

    Zu Neue Frage 2: Einfach trennen was zu trennen ist.
    Zu Neue Frage 3: Lies nach was Events und Delegates sind (http://msdn.microsoft.com/en-us/library/edzehd2t.aspx)



  • theta schrieb:

    Ja, genau so meinte ich das.

    Okay, dann hab ich das offenbar kapiert. 🕶

    theta schrieb:

    ref class MyObject;
    
    ref class Form1 : Form
    {
    public:
       void SetMyObject(MyObject^ myObject)
       {
          // ...
       }
    };
    

    Ja, so hab ichs auch gemeint. Klappt das gleiche Spiel denn auch mit einem Pointer auf ein unmanaged Objekt? (dann mit * statt ^)

    theta schrieb:

    Der Rest deines Zitates ist etwas wirr...

    Ich meinte Folgendes: Angenommen ich habe zwei Forms, und instantiiere form2 aus form1 heraus (beispielsweise ausgelöst von einem Buttonklick auf form1). Dann könnte ich in form2 doch ein beliebiges Daten-Objekt erzeugen, welches ich durch einen Funktionsaufruf ("form1->SetMyObject()") in form1 bekannt mache, bevor form2 geschlossen wird.
    (mit return könnte man den Pointer auf das neue Objekt vermutlich ja auch zurückgeben, aber es geht mir ums Prinzip, ob das auch über einen Funktionsaufruf möglich wäre.)

    theta schrieb:

    Einfach trennen was zu trennen ist.

    Ganz konkret: Welche Methoden meint er, die in form1.h ungünstigerweise vom Formdesigner implementiert werden? Ich sehe - wie gesagt - hier innerhalb dieser Datei nur die Funktionen, die eben von den Eventhandlern aufgerufen werden. Meint er die, oder was anderes?

    theta schrieb:

    Zu Neue Frage 3: Lies nach was Events und Delegates sind (http://msdn.microsoft.com/en-us/library/edzehd2t.aspx)

    Alles klar, mach ich.

    Danke für die Zeit, die Du Dir nimmst 👍 so langsam lichtet sich bei mir der Vorhang, und ich begreife die Sachen ein bischen, die in der form1.h stehen.



  • Ich sehe - wie gesagt - hier innerhalb dieser Datei nur die Funktionen, die eben von den Eventhandlern aufgerufen werden. Meint er die, oder was anderes?

    Ja, die. Auch alle andern, die möglich sind. Der vom Designer genrierte Code (in der entsprechenden Region) geht nicht.



  • theta schrieb:

    Ich sehe - wie gesagt - hier innerhalb dieser Datei nur die Funktionen, die eben von den Eventhandlern aufgerufen werden. Meint er die, oder was anderes?

    Ja, die. Auch alle andern, die möglich sind. Der vom Designer genrierte Code (in der entsprechenden Region) geht nicht.

    Mit "alle andern" meinst Du das, was ich ggf. selbst noch reinprogrammieren will?

    Zur Durchführung... denn ich kann die Funktionen ja nicht einfach nur ausschneiden. Soll ich also nur eine Deklaration dieser Funktion(en) in der ursprünglichen .h lassen, also beispielsweise so:

    private: System::Void openFileDialog1_FileOk(System::Object^  sender, System::ComponentModel::CancelEventArgs^  e);
    

    ...und die Implementierung, also den Code, in eine cpp verfrachten, in welche die form1.h ihrerseits inkludiert wird?

    Dann gibt es ja ein Problem: Die in die cpp ausgelagerte Funktion steht dann ja ausserhalb der Klassenklammern, die in der .h stehen. Wie müsste die zugehörige Funktion in der cpp korrekt aussehen, kann mir das jemand mal ganz kurz sagen?

    Bei einfachen Klassen-Funktionen, die in einer cpp implementiert werden, schreibt man ja z.B.:

    void klasse::funktion() {Code};
    

    ...muß das also dementsprechend auch so in die cpp rein?

    System::Void Form1::openFileDialog1_FileOk(System::Object^  sender, System::ComponentModel::CancelEventArgs^  e) {Code}
    

    Danke euch!



  • Obige Frage hat sich erledigt, es funktioniert auf diese Art.

    Die nächste Frage ist:

    Ich kann ja an Form2 über dessen Konstruktur einen Pointer auf Form1 übergeben (mit (this)), womit ich innerhalb von Form2 auf Properties von Form1 zugreifen kann. Das klappte in meinem Versuch auch.
    Wie kann ich nun aber auf Elemente innerhalb von Form1 zugreifen, also z.B. auf den Text einer auf Form1 befindlichen Text-Box?

    Ich dachte, das müsste wohl so gehen, tuts aber nicht:

    pointer->textBox1->Text="hallo";
    

    Ich konnte aber durchaus alternativ den kompletten Pointer auf die TextBox selbst übergeben, und dann auf deren "Text" zugreifen.

    Gibt es eine Möglichkeit, anhand eines übergebenen Pointers herauszufinden, welche Objekte (hier die TextBox) auf diesem Objekt derzeit vorhanden sind, wie die heißen, und welche Pointer auf sie zeigen?

    Danke 🙂


Anmelden zum Antworten