[gelöst] Nachhilfe Klassen -> Variablenübergabe



  • Ich hab die Grundzüge meines Projekts nun nahezu beendet, eh ich nun in den letzten Zyklus gehe möchte ich meine SourceCode noch etwas überarbeiten und besser Strukturieren. Unter anderem möchte ich noch eine Storage-Klasse erstellen. Aber ich hab immer wieder Probleme mit der Variablen-Übergabe zwischen den Klassen.

    Im moment sieht das ganze quasi so aus.

    filea.cpp

    #include filea.h
    #include function.h
    
    function x ()
    // ruft Dialog a auf
    
    function y ()
    // ruft Dialog b auf
    
    function z ()
    // ruft Dialog c auf
    

    filea.h

    protected:
       nötiges functionen etc um die Dialoge aufzurufen.
    puplic:
       int id;
    

    Dialoga.cpp

    #include "dialoga.h"
    #include "filea.h"
    #include "function.h"
    
    // konstruktor, klasse etc. für Dialog a
    

    dialoga.h

    class Dialoga: public wxDialog
    {
      protected:
        // nötigen deklarationen für die Dialogelemente, eventhandler etc.
    }
    

    in der function.cpp hab ich die Datenbankfunktionen ausgelagert, durch einbinden der function.h kann ich auf diese von überall zugreifen

    Wenn ich nun im Dialog A die Puplic Variable "id" nutzen möchte bekomm ich alle möglichen Fehlermeldungen je nachdem was ich Versuche von "not declared in this scope" bis "expect irgendwas before . oder ->".
    Irgendwie bekomm ich das mit der Sache nicht in den Griff trotz Internetrecherche und 2 Ebooks die ich hier habe.

    Gibts da draussen jemand der sich die Zeit nimmt mir das nochmal verständlich zu erklären? Wäre echt super.

    Der Nala



  • Zeig mal den Code, der den Fehler beinhaltet (inkl. Deklarationen usw.).



  • Da ich meinen Code in ne ganze Menge Datein verteilt habe und hier nicht den Rahmen sprengen will .....
    http://rapidshare.com/files/380657380/SEAdmin.rar.html

    Die Datein um die es hauptsächlich geht sind
    SEAGui.cpp + SEAGUI.h -> erstellt durch wxFormbuilder
    SEAdmin.cpp + SEAdmin.h -> dort sind die ganzen "Hauptmenü-Funktionen" drin
    function.h -> Datenbankdefinitionen

    EDIT: Danke schon mal für den Versuch mir das vielleicht näher zu bringen 😃

    EDIT2: Falls du den Code selbst mal kompilieren willst kann ich dir auch gern nochd ie nötigen dlls dazu reichen ....



  • Ehrlich gesagt habe ich keine Lust, mir den ganzen Source zu ziehen, zu kompilieren usw. Kannst du nicht bitte ein kleines Minimal-Beispiel basteln, das den Fehler aufweist? Das wäre so der übliche Weg (bei dem sich verständlicherweise viel mehr Helfer finden dürften, da deutlich weniger Aufwand).

    Tatsache ist schon mal, dass der Compiler deine Klasseninstanz in diesem Scope, in dem du versuchst, auf ein Member zuzugreifen, nicht kennt.



  • Ok .... dann mal die Datein um die es geht ... ich hab mal der übersichthalber größtenteils den Code aus dem Formbuilder entfernt.

    SEAdminApp.cpp

    #ifdef WX_PRECOMP
    #include "wx_pch.h"
    #endif
    
    #ifdef __BORLANDC__
    #pragma hdrstop
    #endif //__BORLANDC__
    
    #include "SEAdminApp.h"
    #include "SEAdmin.h"
    #include "SEAGui.h"
    
    IMPLEMENT_APP(SEAdminApp);
    
    bool SEAdminApp::OnInit()
    {
        SEAdminDialog* dlg = new SEAdminDialog(0L);
        dlg->SetIcon(wxICON(aaaa)); // To Set App Icon
        dlg->Show();
        return true;
    }
    

    SEAdminApp.h

    #ifndef SEADMINAPP_H
    #define SEADMINAPP_H
    
    #include <wx/app.h>
    
    class SEAdminApp : public wxApp
    {
        public:
            virtual bool OnInit();
    };
    
    #endif // SEADMINAPP_H
    
    #ifndef SEADMINMAIN_H
    #define SEADMINMAIN_H
    
    #include "SEAdminApp.h"
    #include "SEAGui.h"
    
    #endif // SEADMINMAIN_H
    

    SEAGui.cpp

    #include "SEAGui.h"
    
    SEAdminMain::SEAdminMain( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
    {
    	/// CODE für den Dialog aus wxFormBuilder
    
    	// Connect Events
    	/// EVENTS
    }
    
    SEAdminMain::~SEAdminMain()
    {
    	// Disconnect Events
    	///EVENTS
    
    }
    

    SEAGui.h

    #ifndef __SEAGui__
    #define __SEAGui__
    
    #include <wx/string.h>
    #include <wx/stattext.h>
    #include <wx/gdicmn.h>
    #include <wx/font.h>
    #include <wx/colour.h>
    #include <wx/settings.h>
    #include <wx/textctrl.h>
    #include <wx/button.h>
    #include <wx/sizer.h>
    #include <wx/panel.h>
    #include <wx/checkbox.h>
    #include <wx/statline.h>
    #include <wx/richtext/richtextctrl.h>
    #include <wx/frame.h>
    
    class SEAdminMain : public wxFrame
    {
    	private:
    
    	protected:
    		/// CODE für den Dialog aus wxFormBuilder
    
    		// Virtual event handlers, overide them in your derived class
    
    		/// CODE für den Dialog aus wxFormBuilder
    
    	public:
    		wxButton* m_BTNExit1;
    		wxButton* m_BTNExit;
    
    		SEAdminMain( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("SE Admin 0.0.0"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 1024,768 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
    		~SEAdminMain();
    
    };
    
    #endif //__SEAGui__
    

    function.h

    #ifndef FUNCTION_H
    #define FUNCTION_H
    
    #include "wx/wxsqlite3.h"
    #include "wx/wx.h"
    #include "SEAGui.h"
    
    // Datenbankverbindung herstellen und Datenbank öffnen
    
    inline wxSQLite3Database* initDB(void)
    {
    	wxString SEADB = wxGetCwd() + wxT("/seadb.db");
    	wxSQLite3Database* db = new wxSQLite3Database();
    	db->Open(SEADB);
    	return db;
    }
    
    // Datenbank schließen und Speicher freigeben
    
    inline void clearDB(wxSQLite3Database* db)
    {
    	assert(db != NULL);
    	db->Close();
    	delete db;
    }
    
    // Datenbank für Testzwecke zurücksetzen
    
    inline wxSQLite3Database* resetDB(void)
    {
    	wxString SEADB = wxGetCwd() + wxT("/seadb.db");
    	if (wxFileExists(SEADB))
    	{
    		wxRemoveFile(SEADB);
    	}
    	wxSQLite3Database* db = new wxSQLite3Database();
    	try
        {
            db->Open(SEADB);
            /// Diverse SQL Befehle um Tests möglich zu machen
        }
        catch (wxSQLite3Exception& e)
        {
            wxMessageBox( e.GetMessage() );
        }
        db->Close();
    	return 0;
    }
    
    #endif // FUNCTION_H
    

    Bis hierhin waren das ganze hauptsächliche Files aus dem wxFormbuilder .... nun zu den wichtigen 4.

    SEAdmin.cpp

    #include "SEAdmin.h"
    #include "function.h"
    #include "wx/wx.h"
    #include "SEAGui.h"
    #include "PerDialog.h"
    
    SEAdminDialog::SEAdminDialog( wxWindow* parent )
    :
    SEAdminMain( parent )
    {
    
    }
    
    // Login Funktion -> TODO: PW-encryption / SQL-Injektion abfangen
    
    void SEAdminDialog::m_BTNLoginOnButtonClick( wxCommandEvent& event )
    {
        wxSQLite3Database* db = initDB();
        wxString uname = m_loginusername->GetValue();
        wxString upass = m_loginpassword->GetValue();
        wxString query;
        query.Printf(_("SELECT * FROM users WHERE uname = '%s';"),uname.c_str());
        wxSQLite3ResultSet pass = db->ExecuteQuery(query);
    
    	while (pass.NextRow())
    	{
            wxString up = pass.GetAsString(2);
            if (up == upass)
                {
                    myID = pass.GetInt(0);
                    myLevel = pass.GetInt(5);
                    m_panmainmenu->Show();
                    m_panlogin->Hide();
                    switch (myLevel)
                        {
                            case 99:
    
                                break;
                            default:
    
                                m_BTNmainware->Hide();
                                m_BTNmainvas->Hide();
                                m_BTNmainopts->Hide();
                                m_CBPERBar->Enable(false);
                                m_CBPERCloth->Enable(false);
                                m_CBPERGs->Enable(false);
                                m_CBPERLsk->Enable(false);
                                m_CBPERRun->Enable(false);
                                m_TCPERLoan->Enable(false);
                                break;
                        }
                    }
                    else
                    {
                        wxMessageBox( wxT("Login Fehler!") );
                    }
        }
    	pass.Finalize();
        clearDB(db);
    }
    
    // Exit Funktion - Rausfinden warum es im Mainframe nicht funktioniert ....
    
    void SEAdminDialog::m_BTNExitOnButtonClick( wxCommandEvent& event )
    {
        Close();
    }
    
    // Reset Funktion - Entfernen bevor das erste mal vorgestellt wird
    
    void SEAdminDialog::m_BTNMainPersOnButtonClick( wxCommandEvent& event )
    {
        m_panmainmenu->Hide();
        m_panpersonal->Show();
        switch (myLevel)
                        {
                            case 99:
                            break;
                            default:
                                m_BTNAdmAddNote->Hide();
                                m_BTNAdmKickOff->Hide();
                                m_BTNAdmDetNew->Hide();
                                m_BTNAdmIDfw->Hide();
                                m_BTNAdmIDGoto->Hide();
                                m_TCAdmID->Hide();
                                m_BTNAdmIDbw->Hide();
                                m_TCNotes->Hide();
                                m_STADMmyid->Hide();
                                m_TCAdmMyid->Hide();
                            break;
                        }
    
    	wxString query;
        query.Printf(_("SELECT * FROM users WHERE id = '%i';"),myID);
        wxSQLite3Database* db = initDB();
        wxSQLite3ResultSet details = db->ExecuteQuery(query);
    	m_TCAdmMyid->SetValue(details.GetAsString(0));
    	details.Finalize();
    	filltcs(myID);
    }
    
    // Zurück-Button aus dem Personalmenü zum Mainmenü
    
    void SEAdminDialog::m_BTNPDtPMOnButtonClick( wxCommandEvent& event )
    {
        m_panpersonal->Hide();
        m_panmainmenu->Show();
    }
    
    void SEAdminDialog::m_BTNPerDCOnButtonClick( wxCommandEvent& event )
    {
        PerDialog dialog(NULL, wxID_ANY, wxT("Personal Record"));
        wxString query;
        int dcid;
        dcid = wxAtoi(m_TCPERid->GetValue());
        query.Printf(_("SELECT * FROM users WHERE id = '%i';"),dcid);
        wxSQLite3Database* db = initDB();
        wxSQLite3ResultSet details = db->ExecuteQuery(query);
    	while (details.NextRow())
    	{
            dialog.m_TCDLGDCid->SetValue(details.GetAsString(0));
            dialog.m_TCDLGDCnname->SetValue(details.GetAsString(4));
            dialog.m_TCDLGDCvname->SetValue(details.GetAsString(3));
            dialog.m_TCDLGDCmail->SetValue(details.GetAsString(6));
            dialog.m_TCDLGDChandy->SetValue(details.GetAsString(7));
            dialog.m_TCDLGDCuname->SetValue(details.GetAsString(1));
            dialog.m_TCDLGDCjob->SetValue(details.GetAsString(9));
            dialog.m_TCDLGDCloan->SetValue(details.GetAsString(14));
            if ( details.GetInt(15) == 1)
            {
                dialog.m_CBDLGDCsexm->SetValue(true);
            }
            else
            {
                if ( details.GetInt(15) == 2)
                {
                    dialog.m_CBDLGDCsexw->SetValue(true);
                }
            }
            dialog.m_DPDLGDCbday->SetValue(details.GetDate(8));
            if (details.GetInt(10) == 1)
    	    {
    	        dialog.m_CBDLGDCbar->SetValue(true);
    	    }
    	    if (details.GetInt(11) == 1)
    	    {
    	        dialog.m_CBDLGDCcloth->SetValue(true);
    	    }
    	    if (details.GetInt(12) == 1)
    	    {
    	        dialog.m_CBDLGDCrun->SetValue(true);
    	    }
    	    if (details.GetInt(13) == 1)
    	    {
    	        dialog.m_CBDLGDClsk->SetValue(true);
    	    }
    	    if (details.GetInt(13) == 2)
    	    {
    	        dialog.m_CBDLGDCgs->SetValue(true);
    	    }
    	    if (details.GetInt(16) == 1)
    	    {
    	        dialog.m_CBDLGDCactive->SetValue(true);
    	    }
        }
        details.Finalize();
        clearDB(db);
        switch (myLevel)
        {
            case 99:
            break;
            default:
                dialog.m_TCDLGDCloan->Enable(false);
                dialog.m_CBDLGDCactive->Enable(false);
                dialog.m_CBDLGDCbar->Enable(false);
                dialog.m_CBDLGDCcloth->Enable(false);
                dialog.m_CBDLGDCrun->Enable(false);
                dialog.m_CBDLGDCgs->Enable(false);
                dialog.m_CBDLGDClsk->Enable(false);
            break;
        }
        dialog.ShowModal();
        filltcs(dcid);
    }
    
    void SEAdminDialog::filltcs(int ftcID)
    {
        wxString query;
        query.Printf(_("SELECT * FROM users WHERE id = '%i';"),ftcID);
        wxSQLite3Database* db = initDB();
        wxSQLite3ResultSet details = db->ExecuteQuery(query);
    
    	while (details.NextRow())
    	{
    	    m_TCPERSurname->SetValue(details.GetAsString(4));
    	    m_TCPERName->SetValue(details.GetAsString(3));
    	    m_TCPERMail->SetValue(details.GetAsString(6));
    	    m_TCPERSurname->SetValue(details.GetAsString(4));
    	    m_TCPERUsername->SetValue(details.GetAsString(1));
    	    m_TCPERHandy->SetValue(details.GetAsString(7));
    	    m_TCPERBday->SetValue(details.GetAsString(8));
    	    m_TCPERJob->SetValue(details.GetAsString(9));
    	    m_TCPERLoan->SetValue(details.GetAsString(14));
    	    m_TCPERid->SetValue(details.GetAsString(0));
    	    m_TCAdmID->SetValue(details.GetAsString(0));
    	    if (details.GetInt(10) == 1)
    	    {
    	        m_CBPERBar->SetValue(true);
    	    }
    	    if (details.GetInt(11) == 1)
    	    {
    	        m_CBPERCloth->SetValue(true);
    	    }
    	    if (details.GetInt(12) == 1)
    	    {
    	        m_CBPERRun->SetValue(true);
    	    }
    	    if (details.GetInt(13) == 1)
    	    {
    	        m_CBPERLsk->SetValue(true);
    	    }
    	    if (details.GetInt(13) == 2)
    	    {
    	        m_CBPERGs->SetValue(true);
    	    }
    	    if (details.GetInt(15) == 1)
    	    {
    	        m_CBPERSexm->SetValue(true);
    	    }
    	    if (details.GetInt(15) == 2)
    	    {
    	        m_CBPERSexw->SetValue(true);
    	    }
    	    if (details.GetInt(16) == 1)
    	    {
    	        m_CBPERAct->SetValue(true);
    	    }
    	    else
    	    {
    	        m_CBPERAct->SetValue(false);
    	    }
    	}
    	details.Finalize();
        wxString query2;
        wxString Notes;
        query2.Printf(_("SELECT vname, nname, supid, wann, notiz FROM users AS u INNER JOIN notes AS n ON u.id = n.supid WHERE uid = '%i';"), ftcID);
        try
        {
            wxSQLite3ResultSet infos = db->ExecuteQuery(query2);
            while (infos.NextRow())
            {
                Notes.Append(infos.GetAsString(0) << wxT(" ") << infos.GetAsString(1) << wxT(" schrieb am ") << infos.GetAsString(3) << wxT(": \n"));
                Notes.Append(infos.GetAsString(4) << wxT("\n"));
            }
            infos.Finalize();
        }
        catch (wxSQLite3Exception& e)
        {
            wxMessageBox( e.GetMessage() );
        }
        clearDB(db);
        m_TCNotes->SetValue(Notes);
    	return;
    }
    

    SEAdmin.h

    #ifndef __SEAdmin__
    #define __SEAdmin__
    
    /**
    @file
    Subclass of SEAdminMain, which is generated by wxFormBuilder.
    */
    
    #include "SEAGui.h"
    
    //// end generated include
    
    /** Implementing SEAdminMain */
    class SEAdminDialog : public SEAdminMain
    {
    	protected:
    		// Handlers for SEAdminMain events.
            .
            .
            .        
    		void filltcs(int myID);
    	public:
    		/** Constructor */
    		SEAdminDialog( wxWindow* parent );
    		int myID;
            int myLevel;
    	//// end generated class members
    
    };
    
    #endif // __SEAdmin__
    

    PerDialog.h

    #ifndef _PERDIALOG_H_
    #define _PERDIALOG_H_
    
    #include "wx/wx.h"
    #include <wx/datectrl.h>
    
    /*!
    * PersonalRecordDialog class declaration
    */
    
    class PerDialog: public wxDialog
    {
    DECLARE_CLASS( PerDialog )
    DECLARE_EVENT_TABLE()
    
    protected:
        .
        .
        .
    
    	virtual void m_BTNDLGSaveOnClicked( wxCommandEvent& event );        // Warum funktioniert hier Event.skip nicht wo es an andere Stelle bleiben kann
    
    public:
    //// Constructors
    
        .
        .
        .
        PerDialog();
    
        PerDialog(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = wxT("Personal Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU );
    
        /// Member initialization
        void Init();
    
        /// Creation
        bool Create( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = wxT("Personal Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU );
    
        /// Create Controls
    
        void CreateControls();
    
        /// Data members
    
    };
     #endif
    

    PerDialog.cpp

    #include "wx/wx.h"
    #include "PerDialog.h"
    #include "function.h"
    
    /*!
    * PersonalRecordDialog type definition        // Diverse Teile aus GUI-Programmning Example - Versuch zu Optimieren für wxformbuilder
    */
        IMPLEMENT_CLASS( PerDialog, wxDialog )
    /*!
    * PersonalRecordDialog event table definition
    */
        BEGIN_EVENT_TABLE( PerDialog, wxDialog )
        END_EVENT_TABLE()
    /*!
    * PerDialog constructors
    */
        PerDialog::PerDialog( )
        {
            Init();
        }
    PerDialog::PerDialog( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
    {
        Init();
        Create(parent, id, caption, pos, size, style);
    }
    
    /// Initialization
    void PerDialog::Init( )
    {
    
    }
    
    /*!
    * PersonalRecord creator
    */
    bool PerDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
    {
        SetExtraStyle(wxWS_EX_BLOCK_EVENTS|wxDIALOG_EX_CONTEXTHELP);
        if (!wxDialog::Create( parent, id, caption, pos, size, style ))
        return false;
    
        /// CODE fpr den Dialog aus wxFormBuilder
    
    	// Connect Events
    	m_BTNDLGDCSave->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PerDialog::m_BTNDLGSaveOnClicked ), NULL, this );
    
        return true;
    }
    /*!
    * Control creation for PersonalRecordDialog
    */
    
    void PerDialog::m_BTNDLGSaveOnClicked( wxCommandEvent& event )
    {
        int myID = wxAtoi(m_TCDLGDCid->GetValue());
        wxString nname = m_TCDLGDCnname->GetValue();
        wxString vname = m_TCDLGDCvname->GetValue();
        wxString email = m_TCDLGDCmail->GetValue();
        wxString handy = m_TCDLGDChandy->GetValue();
        wxString uname = m_TCDLGDCuname->GetValue();
        wxString job = m_TCDLGDCjob->GetValue();
    

    Die PerDialog.cpp sollte bis hier her reichen .... wie man sieh würde ich eben hier gern die Puplic-Varible "myID" wieder benutzen .... da ich das ganze nicht hinbekommen habe, hab ich mir halt damit geholfen das ich einen TextCtrl beim Aufrufen mit dem Wert gefüllt habe und wieder ausgelesen.



  • Das hat eigentlich reinb gar nix mit Gui-Programmierung zu tun, jedenfalls dein Problem. -> falsches Unterforum
    Dir ist klar, dass jenes "myID" in einer ganz anderen Klasse liegt? Warum solltest du aus PerDialog plötzlich ohne ein SeAdminDialog-Objekt auf einen Member jener Klasse zugreifen können?
    Außerdem ist dein "Aussschnitt" der Fehlermeldung nicht zu gebrauchen. Poste eine ordentliche Fehlermeldung und vor allem Code, bei dem die Fehlermeldung auftritt. Wenn du den Fehler in "PerDialog::m_BTNDLGSaveOnClicked" durch einen Workaround behebst, ist das schön für dich, aber helfen kann man dir dabei nicht mehr.
    Und ein reduziertes Minimalbeispiel ist das immer noch nicht. Zighundert Zeilen Code wird hier keiner einfach so durchgehen und dir debuggen...



  • Man ist in einer schwierigen Lage wenn man etwas nicht kann und erklären soll was man nicht kann. Mein Problem mit dem Minimalbeispiel ist doch das, das wenn ich soweit durch das Thema durchgestiegen wäre das ich mir dazu einfach mal nen Minimalbeispiel aus dem Ärmel schüttel das Thema nicht "Nachhilfe" sondern eher "Schaut her was ich kann" heißen würde. Also hab ich versucht den Code den es betrifft so weit wie möglich zu reduzieren um euch ein klein wenig einen Einblick in mein Problem zu geben. Dabei erwarte ich schon gar nicht das mit jemand meinen Code in irgend einer weise debugged - ich bin mein Leben lang autodidakt, angefangen vor fast 20 Jahren mit Basic bis in letzter Zeit C++ mit der Unterstützung durch wxWidgets. Ein erfahrener Programmierer läuft vor meinem Code schreiend weg, denke ich ....

    Der Punkt ist nun das ich mich in einem Thema wo ich extreme schwächen habe und das ganze selbst mit Literatur nicht gebacken bekomme, versuche mich zu verbessern, und eher im Eingangspost ja nach einem für mich verständlichen Beispiel gefragt hatte.

    Und dazu kann ich dann nur folgendes Sagen, ja mir ist klar das die Variable in einer anderen Klasse liegt, und ich möchte sie, wie im ersten Post geschrieben, ja sogar noch in eine 3. auslagern. Also die für euch wahrscheinlich einfache Frage -> wo und wie erstelle ich das Objekt das ich auf die Variable zugreifen kann.



  • Vergesst das Thema einfach ... hab bei der suche nach einem minimal-Beispiel endlich ne Seite gefunden die das Thema wirklich sehr anschaulich darstellt ...

    Ich weiß nun was ich tun muss, und ich kann nun Anfangen meinen Code zu Optimieren.

    Danke an jene, die sich die Masse an Code trotzdem überflogen haben ... hoffe der Schock war nicht allzu groß 😃


Log in to reply