auf membervariable in static funktion zurückgreifen



  • Hallo
    ich hab folgendes Probelm ich will ein OpenGL programm schreiben und zwar in C++
    leider kann ich hier auf keine Membervariable zurückgreifen. da ich Display als static declariern muss weil die
    opengl Funktion glutDisplayFunk als übergabewert eine Funktion und keine Methode erwartet.
    hat hierfür jemand eine Lösung wie ich in der static Funktion display dennoch auf Membervariablen zurückgreifen kann???
    bin dankbar für jeden hinweis

    mfg tobe 22

    class opendisplay
    {
      public:
       opendisplay(){}
      ~opendisplay(){}
    
      int  startshowimag()
     {  //...
        glutDisplayFunc (display);  //hier erwartet opengl eine funktion und keine methode weshalb ich display als static declarier
        //...
    	glutMainLoop (); 
         return 0;
       }
    
       static void display (void) 
      {
    	 hallo=6; //somit kann ich hier auf keine membervariable zurückgreifen :-( aber genau das will ich!!!
     	 //...
      }	
    	private:
    	int hallo;
    
    };
    
    int main ()
    {
      opendisplay a;
      a.startshowimag();
      return 0;
    }
    


  • Auf die Member welches Objekts willst du denn zugreifen. 😉
    Äehm..., du merkst das Problem (und weshalb das nicht geht) 🙄



  • na ich möchte in der
    "static void display(void)"
    auf die variable
    "hallo2 zugreifen.

    aber das muss doch irgendwie möglich sein....





  • Redhead schrieb:

    Auf die Member welches Objekts willst du denn zugreifen. 😉
    Äehm..., du merkst das Problem (und weshalb das nicht geht) 🙄

    er merkt es nicht 🤡

    mal schaun wie lang es dauert, bis ihm ein licht aufgeht 😃



  • du kannst ein funktionsobjekt erstellen. wenn du einen operator() definierst, dann ist der zeiger auf das objekt auch gleichzeitig ein zeiger auf die operator() methode. du kannst dann an die opengl-funktion anstelle eines funktionszeigers den zeiger auf das objekt übergeben. und du brauchst dann noch nicht mal einen cast.



  • Mal schaun wie lange es dauert, bis ihr ihm ne Lösung anbieten könnt. 🙄

    Ach ne, vielleicht hat er ja so lange garnicht Zeit.

    Du könntest die Klasse opendisplay als Singleton(google-Stichwort) implementieren, und in der static-Methode den Aufruf nur an die Instanz Deines Singletons weiterreichen.

    Allerdings kannst Du damit halt nur noch ein solches opendisplay-Objekt in Deinem Programm haben. Genügt aber meistens.

    MfG Jester



  • Konfusius schrieb:

    du kannst ein funktionsobjekt erstellen. wenn du einen operator() definierst, dann ist der zeiger auf das objekt auch gleichzeitig ein zeiger auf die operator() methode. du kannst dann an die opengl-funktion anstelle eines funktionszeigers den zeiger auf das objekt übergeben. und du brauchst dann noch nicht mal einen cast.

    Glaubst Du dadran?

    Das derefernzieren des Zeigers müßte so aussehen: (*p)(), das wird das Framework wohl nicht tun. Abgesehen davon, daß es nicht wüßte wie das geht, weil es ja das this von dem Objekt mit übergeben müßte. Da glut aber ein C-Framework macht es das nicht.

    Warum solte man auch eine Funktion aufrufen können, aber nicht an nen Member dran kommen. 😕



  • class opendisplay
    {
      public:
       opendisplay(){}
      ~opendisplay(){}
    
      int  startshowimag()
     {  //...
        glutDisplayFunc (display);  //hier erwartet opengl eine funktion und keine methode weshalb ich display als static declarier
        //...
        glutMainLoop (); 
         return 0;
       }
    
      void display (void) // kein static mehr nötig
      {
         hallo=6; //somit kann ich hier auf keine membervariable zurückgreifen :-( aber genau das will ich!!!
          //...
      }    
    
      private:
      int hallo;
    
      class display_caller
      {
        opendisplay *od_obj;
    
        public:
        explicit display_caller (opendisplay &od) : od_obj(&od) {}
                ~display_caller();
    
        void operator() () { od_obj->display(); }
      };
    };
    
    int main ()
    {
      opendisplay a;
      opendisplay::display_caller dc(a);
    
      a.startshowimag();
    
      glutDisplayFunk(dc); // keine ahnug, wie glutDisplayFunk() aufgerufen wird
    
      return 0;
    }
    


  • Das geht so nicht. Lies Dir bitte durch warum.

    Kurz: glut braucht einen Pointer auf eine Funktion, die void liefert und auch nicht bekommt. Da kannst Du keinen Zeiger auf ein Objekt angeben.

    Du machst grad den selben Fehler über den Du Dich vorhin lustig gemacht hast.



  • Jester schrieb:

    Das geht so nicht. Lies Dir bitte durch warum.

    und du lies erst mal in deiner c++-einführung nach, warum doch. das man ein funktionsobjekt wie einen funktionszeiger benutzen kann ist ja gerade der witz bei funktionsobjekten!

    EDIT
    ich geb ja zu, das mit dem clown-smiley war nicht so nett. ich gelobe hiermit besserung 😞

    NOCHMAL EDIT
    alles vergessen alles. quatsch. es geht leider doch nicht.



  • Konfusius schrieb:

    das man ein funktionsobjekt wie einen funktionszeiger benutzen kann ist ja gerade der witz bei funktionsobjekten!

    Cool. Zeigst du ein Beispiel, bei dem du ein Funktionsobjekt als Parameter an eine Funktion übergibst, die einen Funktionszeiger erwartet?



  • <<hab mich vertippt, bitte löschen>>



  • Konfusius schrieb:

    und du lies erst mal in deiner c++-einführung nach, warum doch. das man ein funktionsobjekt wie einen funktionszeiger benutzen kann ist ja gerade der witz bei funktionsobjekten!

    Bau einfach mal nen Beispielcode.



  • das thema läßt mir keine ruhe. zwar ist die sache mit den funktionsobjekten doch nicht möglich (ich habe meinen nick nicht zu unrecht ;)), aber ich habe eine andere lösung gefunden. ist allerdings ziemlich hemdsärmlig...

    #include<iostream>
    #include<cstdlib>
    
    using namespace std;
    
    int array[10];
    
    template<class funcT_>
    class method_caller
    {
      unsigned char caller[12];
    
      public:
      void set (void *that, void *func)
      {
        caller[0]  = 0x58; // pop eax
        caller[1]  = 0x68; // push that
        *(unsigned long*)&
        caller[2]  = (unsigned long)(that);
        caller[6]  = 0x50; // push eax
        caller[7]  = 0xE9; // jmp &caller[0]
        *(unsigned long*)&
        caller[8]  = (unsigned long)(func)
                   - (unsigned long)(&caller[12]);
      }
    
      method_caller () {}
      method_caller (const method_caller &smc) { caller=smc.caller; }
      method_caller (void *that, void *func) { set(that,func); }
      ~method_caller () {}
    
      operator funcT_ () { return (funcT_)&caller[0]; }
    };
    
    class sorter
    {
      public:
    
      int (__cdecl less) (const void *arg1p, const void *arg2p);
      typedef int (*less_type)(const void*, const void*);
      method_caller<less_type> less_caller;
    
      enum sort_mode { ascending,descending };
    
      sort_mode mode;
    
      sorter(sort_mode m=ascending) : mode(m)
      {
        int (__cdecl sorter::*lessp)(const void*,const void*)=&sorter::less;
        less_caller.set(this,*(void**)&lessp);
      }
      ~sorter() {}
    };
    
    int
    sorter::less (const void *arg1p, const void *arg2p)
    {
      return ( mode==ascending
             ? *static_cast<const int*>(arg1p)-*static_cast<const int*>(arg2p)
             : *static_cast<const int*>(arg2p)-*static_cast<const int*>(arg1p));
    }
    
    void
    make_random_array ()
    {
      for(int i=0; i<sizeof(array)/sizeof(int); ++i)
        array[i]=rand();
    }
    
    void
    print_array ()
    {
      for(int i=0; i<sizeof(array)/sizeof(int); ++i)
        cout<<array[i]<<endl;
    }
    
    int
    main ()
    {
      srand(0);
    
      make_random_array();
    
      cout<<"unsorted array:"<<endl;
      print_array();
    
      cout<<endl;
    
      qsort((void*)array,sizeof(array)/sizeof(int),sizeof(int),sorter(sorter::ascending).less_caller);
      cout<<"sorted array in ascending order:"<<endl;
      print_array();
    
      cout<<endl;
    
      qsort((void*)array,sizeof(array)/sizeof(int),sizeof(int),sorter(sorter::descending).less_caller);
      cout<<"sorted array in descending order:"<<endl;
      print_array();
    
      return 0;
    }
    

    ob das auch auf anderen compilern als vc++6 geht, weiß ich nicht.



  • Konfusius schrieb:

    zwar ist die sache mit den funktionsobjekten doch nicht möglich (ich habe meinen nick nicht zu unrecht ;)),

    Es wäre aber schön, wenn du deine Meinung nicht immer so überzeugt und vehement vertreten würdest. Dadurch verbreitest du deine Konfusion auf Andere.

    aber ich habe eine andere lösung gefunden. ist allerdings ziemlich hemdsärmlig...

    Das eine Lösung zu nennen, finde ich schon ziemlich daneben. Ich würde das eher einen "blutigen Hack" nennen.



  • mehr als blutig



  • Kann man das nicht mit ner Klassenvariable loesen?



  • #include <iostream>
    
    using namespace std;
    class example
    {
      public:
        example() throw()
        {
          m_nHallo = 0;
        };
        ~example() throw()
        {
        };
    
        int startShowImag(void) throw()
        {
          setExamp(getHallo()); // ms_nExamp den aktuellen Wert von m_nHallo setzen
          glutDisplayFunc(display); // du kannst hier drin jetzt ms_nExamp                 aendern...
          setHallo(); // und hier dann den geaenderten Wert in dein Objekt schmeissen
          //..
          glutMainLoop();
          return 0;
        };
    
        static void display(void) throw()
        {
          ms_nExamp = 6;
        };
    
        static void setExamp(int nInt) throw()
        {
          ms_nExamp = nInt;
        };
    
        static int getExamp(void) throw()
        {
          return ms_nExamp;
        };
    
        void setHallo(void) throw()
        {
          m_nHallo = getExamp();
        };
    
        int getHallo(void) throw()
        {
          return m_nHallo;
        };
    
      private:
        int m_nHallo;
        static int ms_nExamp;
    };
    
    int example::ms_nExamp = 0;
    
    int main(int nArgv, char *apc[])
    {
      example a;
      a.startShowImag();
      cout << a.getHallo() << flush;
    
      return 0;
    }
    

    Duerfte dir helfen 😃



  • Zumindest hab ich gelernt dass dies alles net so einfach möglich ist.

    und ich hab immernoch zeit und hab auch alle postings gelesen um mal ein paar vorurteilen vorzubeugen....

    ich habs bisher einfach mal mit satischen variablen gemacht auch wenn dies net so saueber ist so ist es in dem fall einfach am einfachsten aber danke für alle postings


Anmelden zum Antworten