zeiger in klassen



  • wie benutzt man Zeiger in Klassen ?

    So wie überall anders auch.

    Wo deklarier ich einen Zeiger ?

    Da wo man alle anderen Daten auch deklariert. Im private-Bereich.

    Wenn er unter private deklariert wird
    wie kann man dann drauf zu greifen ?

    Von außen direkt gar nicht. Das ist der Sinn von Kapselung.

    Können dann ale funktionen unte rpublic auf den Zeiger zugreifen ?

    Zugriffsrechte werden nicht durch den Objekttyp beeinflusst. Es gelten also exakt die selben Regeln wie für nicht-Zeigertypen. Methoden einer Klasse haben selbstverständlich Zugriff auf die Instanzvariablen.

    Das man dann halt praktisch ne
    klasse hat um Dateien zu lesen oder in datein zu schreiben ?

    Dafür gibt es in der Standardbibliothek bereits feine Klassen. Für den Anfang nennen wir sie mal ifstream und ofstream.



  • Jo, die fstream sache kenne ich.
    Nur habe ich da eine saceh die ich mit FILE gut lösen konnte
    mit fstream aber keine Lösung gefunden habe.

    Werde das dann mal mit den Zeigern probieren.



  • Vielleicht kann mir Jemand helfen.

    Ich möchte mir einen eigenen Dialog schreiben.
    MessageBox, ShowMessage und MessageDlg gefallen mir alle nicht.

    Doch der Zeiger F funktioniert in der Funktion CreateMyDialog() nicht.

    Warum nicht? Kann mir Jemand helfen?

    Hier der Quelltext

    Unit1.cpp

    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include "MyDialog.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    MyDialog *mDialog;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      mDialog->CreateMyDialog();
    }
    //---------------------------------------------------------------------------
    

    MyDialog.h

    class MyDialog : public TForm
    {
      private:
      TForm *F;
    
      public:
    
      void CreateMyDialog()
      {
        //TForm *F = new TForm(this);  wenn ich so eine neue Form erzeuge geht es
        // doch dann funktioniert F->Close() weiter unten nicht mehr weil F
        // innerhalb der Funktion deklariert wurde
        F->Caption = "Mein neuer Dialog";
        TButton *B = new TButton(this);
        B->Parent = F;
        B->SetBounds(50,50,75,25);
        B->OnClick = MyClick;
        F->ShowModal();
      }
    
      void __fastcall MyClick(TObject *Sender)
      {
        ShowMessage("Das Ereignis MyClick ist eingetreten.");
        F->Close();
      }
    };
    

    Wenn ich das so übersetzen lasse, bekomme ich eine Fehlermeldung (Zugriffsverletzung)



  • Mach es so:

    MyDialog.h

    class MyDialog : public TForm
    {
      private:
      TForm *F;
    
      public:
    
      void CreateMyDialog()
      {
        //TForm *F = new TForm(this);  wenn ich so eine neue Form erzeuge geht es
        // doch dann funktioniert F->Close() weiter unten nicht mehr weil F
        // innerhalb der Funktion deklariert wurde
        //Du willst ja auch keine neue Variable deklarieren, sondern dem Member der Klasse das neue Objekt zuweisen, also
        F = new TForm(this);
        //...
      }
    };
    

    Erklärung steht im Kommmentar.

    Wieso hast du für die Frage eigentlich diesen uralt Thread ausgebuddelt? Hat zwar thematisch was miteinander zu tun, aber trotzdem...

    Felix



  • Die Frage ist, wozu Du überhaupt den TForm-Zeiger benötigst? Wozu brauchst Du überhaupt eine konkrete Instanz von TForm? Meiner Meinung nach brauchst Du eine Instanz von MyDialog...

    Es wäre wohl deutlich günstiger, den Dialog als neues Formular im BCB zu erstellen, aus der Liste der automatisch erzeugten Forumlare herausnehmen und diesen bei Bedarf dann selbst zu instanzieren (abschließendes löschen nicht vergessen). Falls der Dialog nicht Modal ist, kann man ihn auch mit einem andern Formular, oder dem TApplication-Objekt als Owner erzeugen, dann brauchst Du Dich ums löschen nicht zu kümmern. Auch könnte auto_ptr einen Blick wert sein.



  • Erstmal ein Danke für die schnelle Antwort.
    Ausgebuddelt habe ich den Thread, ja weil´s zum Thema passt.

    Doch leider funktioniert das nicht. Ich habe es genau so versucht wie du es beschrieben hast. F = new TForm(this);

    Das Programm läst sich übersetzen, wenn ich auf Button1 clicke bekomme ich folgende Meldung: Womit ich leider garnichts anfangen kann
    ---------------------------
    Debugger Exception Notification
    ---------------------------
    Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00401BAB in module 'Project1.exe'. Write of address 000002F0'. Process stopped. Use Step or Run to continue.
    ---------------------------
    OK Help
    ---------------------------

    Um Joe_M. zu antworten, ich wußte mir einfach nicht anders zuhelfen.
    Aber das Formular im BCB zu erstellen, und aus der Liste der automatisch erzeugten Forumlare zu entfernen ist eine gute Idee. Danke für diese.
    Aber ich glaube meine Klasse ist so wie ich es versuche, etwas flexibler.

    Wissen würde ich gerne trotzdem, warum es auf diesem Wege
    F = new TForm(this);
    nicht geht.

    Andreas



  • So es ist jetzt 4:51 in einer Stunde muß ich zur Arbeit.

    Aber die Nacht hat sich gelohnt.

    Ich kann ja Klassenelemente, auch vor der Definition, der Klasse selbst verwenden.
    Also so

    MyDialog.h

    #ifndef MYDIALOG_H
    #define MYDIALOG_H
    TForm *F;
    class MyDialog : public TForm
    {
      public:
    
      void CreateMyDialog()
      {
        F = new TForm(this);
        F->Caption = "Mein neuer Dialog";
        TButton *B = new TButton(this);
        B->Parent = F;
        B->SetBounds(50,50,75,25);
        B->OnClick = MyClick;
        F->ShowModal();
      }
    
      void __fastcall MyClick(TObject *Sender)
      {
        ShowMessage("Das Ereignis MyClick ist eingetreten.");
        F->Close();
      }
    };
    #endif
    

    Vielen Dank

    Andreas



  • Ich verstehe es trotzdem nicht. Wieso erstellst Du ein Form F, wenn es doch schon das Form MyDialog gibt? Du erstellst ein unsichtbares Form MyDialog, nur um ein (mehr oder weniger abstraktes) Formular vom Typ TForm zu erstellen? MyDialog lässt Du dann vermutlich automatisch erzeugen, zeigst aber niemals an und verwendest es nur als 'Container' für alle manuell erzeugten TForm-Instanzen?



  • Wie würdest du denn eine Klasse schreiben die folgende Funktionen enthält:

    // Ich denke zu dieser Funktion muß ich nichts weiter schreiben
    CreateMessageDialog(String Message,String ResourceDllFileName,String ResourceName,int Buttons);
    
    // Ein PasswortDialog brauche ich immer und immer wieder
    CreatePasswordDialog();
    
    /* Click OK, Verbindung wird konfiguriert wenn alle Edits ausgefüllt wurden.
       Click OK, Verbindung wird aus der Reg. galaden wenn alle Edits leer sind
       Click Speichern, speichert die Verbindunsinformationen nach 
       einem erfolgreich abgeschlossenen Verbindungstest wie Username usw. in der Reg. 
       Wobei das Pass... verschlüsselt gespeichert wird. 
       Der Parameter SaveArea gibt an ob der SpeichernTeil in diesem Dialog sichtbar ist */
    CreateMySQLConnectionDialog(bool SaveArea);
    
    // Ich weiß das es einen fertigen gibt 
    CreateSelectFolderDialog(int Buttons);
    

    Wie lasse ich mir das Formular MyDialog Modal anzeigen?
    Wie bekomme ich Komponenten, oder einen Zeiger auf diese, auf das Formular MyDialog?

    Wie ich schon schrieb, wußte ich mir nicht anders zuhelfen.
    Hilf mir.

    Andreas



  • Gar nicht. Für alle diese Dinge gibt es Standarddialoge in BCB.

    Nachricht ausgeben: ShowMessage() oder Application::MessageBoxA().
    Passwort-Dialog: Wofür? Die Datenbankzugriffskomponenten des BCB erzeugen diesen automatisch.
    MySQL-Connection Dialog: Dies ist wohl der einzige Dialog, den Du selbst machen musst. Aber auch nur dann, wenn Du zwischen beliebigen Servern / Datenbanken wechseln willst. Mach ihn als normales Formular, dann kannst Du ihn auch wie jedes andere Formular im BCB verwenden, inkl. Zugriff auf, auch selbsterstellte, Variablen. Hierzu ist vielleicht die __property Eigenschaft des BCB noch ganz interessant. Damit kann man sich für einfache Datentypen den Getter und Setter sparen.
    Select-Directory Dialog: Dazu würde ich die WinAPI nutzen: SHBrowseForFolder().


Anmelden zum Antworten