Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

1

19.02.2013, 17:40

Map aus Vektoren aus Funktionspointern mit Zeigern auf Instanzmethoden befüllen

Zitat

"Anyone can make the simple complicated. Creativity is making the complicated simple."
(Charles Minguns)

Hallo zusammen!

Es gibt in meinem immer größer werdenden Code einige Stellen, wo die immergleichen Methoden verschiedener Klassen (sei es Release() oder Adapt() oder Update() usw..) aufgerufen werden müssen.
Darum hab ich mir gedacht, eine Klasse zum Verwalten von "Funktionsgruppen" (=Arrays aus Funktionspointern) zu basteln. Diese Klasse besitzt dann nur noch eine Methode names "RunFunctionGroup".
In einen Container (eine Map aus Vektoren dieses Funktionsrumpfes) schmeiss ich dann die Methoden meiner Klassen rein. Alles regelt sich von selbst :)
Ich dachte da an sowas:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using namespace std;
// Map aus Vektoren aus Funktionspointer
map<char*, vector< HRESULT(*)() > > m_CallThisFunc;

// ...
// Zur Gruppe Hinzufügen
void AddFuncToGroup(char* cGroup, HRESULT (* pFunc)(void)) {
    // Adresse zur Funktionsgruppe hinzufügen!
    m_CallThisFunc[cGroup].push_back( pFunc );
}

// ...

// Funktionsgruppe ausführen!
void ExecuteFunctionPool(char* cPoolName) {
                
    HRESULT (* pFunc)(void);
                
    for( size_t i=0;  i< m_CallThisFunc[cPoolName].size(); i++) {
                    
        // Funktionspointer übernehmen!
        pFunc = m_CallThisFunc[cPoolName][i];
                    
        // Ausführen, falls valide Funktion
        if( nullptr != pFunc) {
                        
            // Ausführen!
            pFunc(); 
        }
    }
}



Nun meldet sich ein altbekannter Feind von mir: Zeiger auf Methoden/usw. einer Instanz.
Und zwar hab ich in meiner Klasse ein LPD3DXFONT-Objekt, welches die Methoden OnLostDevice() und UnResetDevice() verwendet:

C-/C++-Quelltext

1
2
3
4
5
6
7
class CText {

// In class CText oder so
LPD3DXFONT m_font;
m_font->OnLostDevice(); // Parameter: void
m_font->OnResetDevice(); // auch void
}


Wie füge ich nun die Adressen dieser Methoden dieses Objekts in einer Instanz der Klasse CText zum Funktionskontainer hinzu??


C-/C++-Quelltext

1
2
3
4
5
6
7
8
// Das geht in die Hose! :(
pTest =  reinterpret_cast<HRESULT(*)()> (Text.m_font->OnLostDevice());

// Funktionspointer zur Gruppe hinzufügen, später ausführe
Manager.AddFuncToGroup( "Sprites", pTest );

// Später dann:
Manager.ExecuteFunctionPool("Sprites");




Ich weiß, dass die Antwort sicher einfach ist. Zeiger und Funktionszeiger, Dereferenzierungen und das Zeugs zählen leider noch nicht zu meinen Stärken.
Ich hab mal alles ausführlich geschrieben damit man es vielleicht in die FAQ setzen kann :)

Danke für jegliche Hilfe!
Mit freundlichen Grüßen
Johannes Schneider
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

2

19.02.2013, 18:49

Hast du dir mal std::mem_fn angesehen? Das ist ein wrapper für Memberfunktionen.

std::mem_fn
:love: := Go;

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

19.02.2013, 19:06

Man, die Namen für STL-Stuff in C++ sind echt ätzend.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

4

19.02.2013, 19:48

Ansosnten: Ziemlich genau sowas (nur in umfangreicher) gibt es mit boost::signals schon. Und es gibt noch diverse andere signal/slot-Bibliotheken mit jeweiligen Stärken/Schwächen. Ein Blick auf die wäre vielleicht gar nicht so verkehrt.
Lieber dumm fragen, als dumm bleiben!

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

19.02.2013, 22:12

Wie füge ich nun die Adressen dieser Methoden dieses Objekts in einer Instanz der Klasse CText zum Funktionskontainer hinzu??

Am besten gar nicht. Anstatt einfach nur irgendwie die Symptome zu lindern, solltest du beim eigentlichen Problem ansetzen: Wieso genau musst du all diese Methoden einander scheinbar völlig fremder Klassen immer wieder gemeinsam aufrufen? Wenn diese Klassen wirklich absolut nichts gemeinsam haben, wie kommt es dann, dass du vor dem Problem stehst, sie alle in einen gemeinsamen Container zu packen?

Es gibt in meinem immer größer werdenden Code einige Stellen, wo die immergleichen Methoden verschiedener Klassen (sei es Release() oder Adapt() oder Update() usw..) aufgerufen werden müssen.

Wenn das tatsächlich so sein muss, können diese Klassen nicht einfach ein gemeinsames Interface implementieren!?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

20.02.2013, 06:39

Viele C++ Entwickler neigen meiner Erfahrung danach Interfaces zu vergessen und es über wilde Pointer oder Templates zu lösen. Ein Interface ist hier in der Tat aber der richtige Ansatz. Intensiver Gebrauch von Interfaces ist übrigens sehr empfehlenswert und garantiert entspanntes Arbeiten.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

7

20.02.2013, 18:34

Also ich hab mir das alles nochmals angesehen und durch den Kopf gehen lassen...

Ich bastel mir das alles auf einem Basisklassen gerüst und vererbe das dann irgendwie weiter.
Das erscheint mir alles doch haariger als ich dachte

Danke jedenfalls.
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

Werbeanzeige