Funktion in einer "spziellen Klasse" zugreifen



  • Schönen guten Abend, meine Frage handelt über das wxWidgets Framework. Ich habe die Frage dennoch hier gestellt, da es sich eig um eine allgemeine Klassen Frage handelt:

    class CTeague_ServerFrame: public wxFrame
    {
        public:
            CTeague_ServerFrame(wxWindow* parent,wxWindowID id = -1);
            virtual ~CTeague_ServerFrame();
            void setlistbox();
    
        private:
            //(*Handlers(CTeague_ServerFrame)
            void OnQuit(wxCommandEvent& event);
            void OnAbout(wxCommandEvent& event);
            void OnButton1Click(wxCommandEvent& event);
            //*)
    
            //(*Identifiers(CTeague_ServerFrame)
            static const long ID_BUTTON1;
            static const long ID_LISTBOX1;
            static const long idMenuQuit;
            static const long idMenuAbout;
            static const long ID_STATUSBAR1;
            //*)
    
            //(*Declarations(CTeague_ServerFrame)
            wxButton* Button1;
            wxStatusBar* StatusBar1;
            wxListBox* ListBox1;
            //*)
    
            DECLARE_EVENT_TABLE()
    };
    

    Wie kann ich jetzt über eine ich nenne es mal "normale Funktion" auf die ListBox1 zu greifen oder allgemein auf eine Funktion innerhalb der Klasse. Ich meine über eine Funktion, bei der nicht CTeague_ServerFrame:: vorsteht. Beispielsweise einfach so:

    int cb_on() {
        CTeague_ServerFrame::setlistbox();
       return 0;
    }
    

    Dann sagt er mir Objekt nicht vorhanden, klar weil er von ausserhalb nicht die Klasse kennt. (setlistbox ist selbstverständlich public)

    Vielen Dank für eure Hilfe(n) 🙂

    Schoenen Abend euch allen.



  • Da die Memberfunktion nicht static ist, brauchst du ein Objekt, um die Funktion darauf aufzurufen.

    Sprich in deinem Beispiel in etwa so:

    int cb_on() {
       CTeague_ServerFrame sf;
       sf.setlistbox();
       return 0;
    }
    


  • ich kann doch kein objekt davon erzeugen, weil ich ja selbst die klasse definiere. Das Objekt wird ja erst viel später erzeugt, und dann soll meine funktion ja ein teil davon sein. Ich kann leider meine Funktion nicht hiermit erzeugen "CTeague_ServerFrame::" , da ich den Zeiger von dieser Funktion für eine Callback Funktion nutzen möchte. Danke aber trotzdem 🙂



  • Warum solltest du kein Objekt erzeugen können?

    Wenn du das Objekt nich in der Funktion erzeugen möchtest, dann übergibst du ihr halt einfach einen Zeiger darauf:

    int cb_on(CTeague_ServerFrame* sf)
       sf->setlistbox();
       return 0;
    }
    


  • Wenn ich das Objekt neu erzeuge funktioniert es nicht, da es ja nicht das Objekt ist welches momentan zu sehen ist.

    bool CTeague_ServerApp::OnInit()
    {
        //(*AppInitialize
        bool wxsOK = true;
        wxInitAllImageHandlers();
        if ( wxsOK )
        {
        	CTeague_ServerFrame* Frame = new CTeague_ServerFrame(0);
        	Frame->Show();
        	SetTopWindow(Frame);
        }
        //*)
        return wxsOK;
    
    }
    

    Hier wird es doch erzeugt. Ich befinde mich doch aber noch in der Klassen Definition. Wie soll ich denn den Zeiger in diese Funktion (ausserhalb der Klasse) bekommen? (Habe ich gerade mal versucht, ich kann den Zeiger nach Init nicht übergeben.) Noch Vorschläge 🙂 ?



  • Speicher einfach den CTeague_ServerFrame zeiger in deiner CTeague_ServerApp klasse?



  • Okay, wie kann ich dann aber aus dem Hauptprogramm zugreifen? Bin ja dann auch nicht in der Klasse. Und wenn ich eine globale Variable habe um den Zeiger zu speichern geht es auch nicht. Danke und weiter gehts 😃



  • bool CTeague_ServerApp::OnInit()
    {
        //(*AppInitialize
        bool wxsOK = true;
        wxInitAllImageHandlers();
        if ( wxsOK )
        {
            CTeague_ServerFrame* Frame = new CTeague_ServerFrame(0);
            Frame->Show();
            Frame->setlistbox (); // was ist daran nicht gut?
            SetTopWindow(Frame);
        }
        //*)
        return wxsOK;
    
    }
    

    Ich versteh wirklich nicht, was du genau willst. Wo bist du genau und auf was möchtest du zugreifen? - Fakt ist, dass wenn du ein Objekt von dem Typen hast, kannst du ohne Probleme setlistbox aufrufen. Du hast, denke ich ein ein anderes Verständnis Problem.



  • mmarcel1 schrieb:

    Okay, wie kann ich dann aber aus dem Hauptprogramm zugreifen? Bin ja dann auch nicht in der Klasse. Und wenn ich eine globale Variable habe um den Zeiger zu speichern geht es auch nicht. Danke und weiter gehts 😃

    Genau das habe ich befürchtet, dass du ein solches Problem hast. 😉

    Warum sollte ein globale Variable nicht gehen? (ob es gut ist das zu machen ist eine andere Frage, aber du solltest dein Problem ein wenig genauer schildern.)



  • drakon schrieb:

    bool CTeague_ServerApp::OnInit()
    {
        //(*AppInitialize
        bool wxsOK = true;
        wxInitAllImageHandlers();
        if ( wxsOK )
        {
            CTeague_ServerFrame* Frame = new CTeague_ServerFrame(0);
            Frame->Show();
            Frame->setlistbox (); // was ist daran nicht gut?
            SetTopWindow(Frame);
        }
        //*)
        return wxsOK;
    
    }
    

    Ich versteh wirklich nicht, was du genau willst. Wo bist du genau und auf was möchtest du zugreifen? - Fakt ist, dass wenn du ein Objekt von dem Typen hast, kannst du ohne Probleme setlistbox aufrufen. Du hast, denke ich ein ein anderes Verständnis Problem.

    Das ich mich hier in einer anderen Klasse befinde. Was ich möchte ist, innerhalb der Klasse CTeague_ServerFrame mit einer öffentlichen (nicht zur Klasse gehörenden) Funktion, auf die Klassen Elemente zuzugreifen.



  • Datei - CTeague_ServerMain.cpp

    /***************************************************************
     * Name:      CTeague_ServerMain.cpp
     * Purpose:   Code for Application Frame
     * Author:    stu [:-) ()
     * Created:   2009-11-03
     * Copyright: stu [:-) ()
     * License:
     **************************************************************/
    
    #include "CTeague_ServerMain.h"
    #include <wx/msgdlg.h>
    
    //(*InternalHeaders(CTeague_ServerFrame)
    #include <wx/intl.h>
    #include <wx/string.h>
    //*)
    
    #ifdef DLL_EXPORT
    #define DLLDIR  __declspec(dllexport)
    #else
    #define DLLDIR  __declspec(dllimport)
    #endif
    #include <windows.h>
    
    typedef int (*Callback)();
    
    extern "C" {
        // DLLDIR double SomeFunction (const LPCSTR sometext);
        DLLDIR int STDCALL dll_startserver(Callback cb_onf, Callback cb_off);
        // DLLDIR void STDCALL dll_newclient();
    }
    
    int cb_on() {
        // wxMessageBox(_("On"), _("Welcome to..."));
        // saveFrame1->ListBox1->Append(_("a12"));
       return 0;
    }
    
    int cb_off() {
        // wxMessageBox(_("Off"), _("Welcome to..."));
        return 0;
    }
    
    //helper functions
    enum wxbuildinfoformat {
        short_f, long_f };
    
    wxString wxbuildinfo(wxbuildinfoformat format)
    {
        wxString wxbuild(wxVERSION_STRING);
    
        if (format == long_f )
        {
    #if defined(__WXMSW__)
            wxbuild << _T("-Windows");
    #elif defined(__UNIX__)
            wxbuild << _T("-Linux");
            #define STDCALL __attribute__((stdcall))
    #endif
    
    #if wxUSE_UNICODE
            wxbuild << _T("-Unicode build");
    #else
            wxbuild << _T("-ANSI build");
    #endif // wxUSE_UNICODE
        }
    
        return wxbuild;
    }
    
    //(*IdInit(CTeague_ServerFrame)
    const long CTeague_ServerFrame::ID_BUTTON1 = wxNewId();
    const long CTeague_ServerFrame::ID_LISTBOX1 = wxNewId();
    const long CTeague_ServerFrame::idMenuQuit = wxNewId();
    const long CTeague_ServerFrame::idMenuAbout = wxNewId();
    const long CTeague_ServerFrame::ID_STATUSBAR1 = wxNewId();
    //*)
    
    BEGIN_EVENT_TABLE(CTeague_ServerFrame,wxFrame)
        //(*EventTable(CTeague_ServerFrame)
        //*)
    END_EVENT_TABLE()
    
    CTeague_ServerFrame::CTeague_ServerFrame(wxWindow* parent,wxWindowID id)
    {
        //(*Initialize(CTeague_ServerFrame)
        wxMenuItem* MenuItem2;
        wxMenuItem* MenuItem1;
        wxMenu* Menu1;
        wxGridSizer* GridSizer1;
        wxMenuBar* MenuBar1;
        wxMenu* Menu2;
    
        Create(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("id"));
        GridSizer1 = new wxGridSizer(0, 3, 0, 0);
        Button1 = new wxButton(this, ID_BUTTON1, _("sS"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
        GridSizer1->Add(Button1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
        ListBox1 = new wxListBox(this, ID_LISTBOX1, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_LISTBOX1"));
        ListBox1->Append(_("a"));
        GridSizer1->Add(ListBox1, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
        SetSizer(GridSizer1);
        MenuBar1 = new wxMenuBar();
        Menu1 = new wxMenu();
        MenuItem1 = new wxMenuItem(Menu1, idMenuQuit, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
        Menu1->Append(MenuItem1);
        MenuBar1->Append(Menu1, _("&File"));
        Menu2 = new wxMenu();
        MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
        Menu2->Append(MenuItem2);
        MenuBar1->Append(Menu2, _("Help"));
        SetMenuBar(MenuBar1);
        StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
        int __wxStatusBarWidths_1[1] = { -1 };
        int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
        StatusBar1->SetFieldsCount(1,__wxStatusBarWidths_1);
        StatusBar1->SetStatusStyles(1,__wxStatusBarStyles_1);
        SetStatusBar(StatusBar1);
        GridSizer1->Fit(this);
        GridSizer1->SetSizeHints(this);
    
        Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&CTeague_ServerFrame::OnButton1Click);
        Connect(idMenuQuit,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CTeague_ServerFrame::OnQuit);
        Connect(idMenuAbout,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CTeague_ServerFrame::OnAbout);
        //*)
    }
    
    CTeague_ServerFrame::~CTeague_ServerFrame()
    {
        //(*Destroy(CTeague_ServerFrame)
        //*)
    }
    
    void CTeague_ServerFrame::OnQuit(wxCommandEvent& event)
    {
        Close();
    }
    
    void CTeague_ServerFrame::OnAbout(wxCommandEvent& event)
    {
        wxString msg = wxbuildinfo(long_f);
        wxMessageBox(msg, _("Welcome to..."));
    }
    
    void CTeague_ServerFrame::OnButton1Click(wxCommandEvent& event)
    {// Start Server
        Button1->Enable(false);
        dll_startserver(&cb_on, &cb_off);
    
    }
    

    Datei - CTeague_ServerMain.h

    /***************************************************************
     * Name:      CTeague_ServerMain.h
     * Purpose:   Defines Application Frame
     * Author:    stu [:-) ()
     * Created:   2009-11-03
     * Copyright: stu [:-) ()
     * License:
     **************************************************************/
    
    #ifndef CTEAGUE_SERVERMAIN_H
    #define CTEAGUE_SERVERMAIN_H
    
    //(*Headers(CTeague_ServerFrame)
    #include <wx/sizer.h>
    #include <wx/menu.h>
    #include <wx/listbox.h>
    #include <wx/button.h>
    #include <wx/frame.h>
    #include <wx/statusbr.h>
    //*)
    
    class CTeague_ServerFrame: public wxFrame
    {
        public:
            CTeague_ServerFrame(wxWindow* parent,wxWindowID id = -1);
            virtual ~CTeague_ServerFrame();
    
        private:
            // my_own
    
            //(*Handlers(CTeague_ServerFrame)
            void OnQuit(wxCommandEvent& event);
            void OnAbout(wxCommandEvent& event);
            void OnButton1Click(wxCommandEvent& event);
            //*)
    
            //(*Identifiers(CTeague_ServerFrame)
            static const long ID_BUTTON1;
            static const long ID_LISTBOX1;
            static const long idMenuQuit;
            static const long idMenuAbout;
            static const long ID_STATUSBAR1;
            //*)
    
            //(*Declarations(CTeague_ServerFrame)
            wxButton* Button1;
            wxStatusBar* StatusBar1;
            wxListBox* ListBox1;
            //*)
    
            DECLARE_EVENT_TABLE()
    };
    
    #endif // CTEAGUE_SERVERMAIN_H
    

    Datei - CTeague_ServerApp.h

    /***************************************************************
     * Name:      CTeague_ServerApp.h
     * Purpose:   Defines Application Class
     * Author:    stu [:-) ()
     * Created:   2009-11-03
     * Copyright: stu [:-) ()
     * License:
     **************************************************************/
    
    #ifndef CTEAGUE_SERVERAPP_H
    #define CTEAGUE_SERVERAPP_H
    
    #include <wx/app.h>
    
    class CTeague_ServerApp : public wxApp
    {
        public:
            virtual bool OnInit();
    };
    
    #endif // CTEAGUE_SERVERAPP_H
    

    Datei - CTeague_ServerApp.cpp

    /***************************************************************
     * Name:      CTeague_ServerApp.cpp
     * Purpose:   Code for Application Class
     * Author:    stu [:-) ()
     * Created:   2009-11-03
     * Copyright: stu [:-) ()
     * License:
     **************************************************************/
    
    #include "CTeague_ServerApp.h"
    
    //(*AppHeaders
    #include "CTeague_ServerMain.h"
    #include <wx/image.h>
    //*)
    
    IMPLEMENT_APP(CTeague_ServerApp);
    
    bool CTeague_ServerApp::OnInit()
    {
        //(*AppInitialize
        bool wxsOK = true;
        wxInitAllImageHandlers();
        if ( wxsOK )
        {
        	CTeague_ServerFrame* Frame = new CTeague_ServerFrame(0);
        	Frame->Show();
    
        	SetTopWindow(Frame);
        }
        //*)
        return wxsOK;
    
    }
    


  • Was spricht denn gegen sowas?

    foo.hpp

    namespace Globals
    {
       CTeague_ServerFrame* Frame;
    }
    

    main.cpp

    void OnInit()
    {
       Globals::Frame = new CTeague_ServerFrame(0);
    }
    

    bar.cpp

    void bar::on()
    {
      Globals::Frame->setlistbox();
    }
    


  • Ich hatte ein sehr gutes Gefühl als ich deinen Vorschlag compiliert habe ^^, nur dann bekomme ich folgenden Error:

    C:/SourceCode/Libraries/wxWidgets2.8/include/wx/app.h:(.bss+0x0): multiple definition of `Globals::Frame'

    Mhhh



  • Da hilft es ein extern vor die Deklaration zu setzen.



  • Braunstein schrieb:

    Da hilft es ein extern vor die Deklaration zu setzen.

    Ist es so gemeint?

    #include "CTeague_ServerMain.h"
    
    namespace Globals
    {
       extern CTeague_ServerFrame* Frame;
    }
    

    undefined reference to 'Globals::Frame'

    Danke für eure Hilfe.



  • im header (wo du den ptr deklarierst), sollte das extern davor.

    im source (wo du den ptr definierst bzw initialisierst), sollte _kein_ extern davor...

    bb



  • So, ich schätze mal das ich genau das bereits gemacht habe, was du vorgeschlagen hast.
    Nun habe ich folgendes Problem (ich habe meine neue Header Datei jetzt einfach zentral includiert):

    D:\projects\CTeague_Server\foo.hpp|5|error: expected constructor, destructor, or type conversion before '*' token|

    Es bezieht sich auf folgende Zeile:
    CTeague_ServerFrame* Frame;

    Vielen Dank :-))



  • mmarcel1 schrieb:

    So, ich schätze mal das ich genau das bereits gemacht habe, was du vorgeschlagen hast.
    Nun habe ich folgendes Problem (ich habe meine neue Header Datei jetzt einfach zentral includiert):

    D:\projects\CTeague_Server\foo.hpp|5|error: expected constructor, destructor, or type conversion before '*' token|

    Es bezieht sich auf folgende Zeile:
    CTeague_ServerFrame* Frame;

    Vielen Dank :-))

    Hängt das vielleicht damt zusammen das die Klasse CTeague_ServerFrame Eigenschaften und so vererbt bekam?



  • mhh *push* 😞 Keine Idee?



  • Zeig mal die Umgebung der Zeile, wo der Fehler auftritt.


Log in to reply