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

Timmyew

Treue Seele

  • »Timmyew« ist der Autor dieses Themas

Beiträge: 128

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

1

18.06.2021, 13:10

C++ procedure of object Methodenzeiger wie in Delphi

Guten Morgen,

ich suche nach einer Möglichkeit einen Methodenzeiger zu deklarieren, sodass ich ihn wie in Delphi nutzen kann.

Delphi Syntax:

C-/C++-Quelltext

1
2
type
  TMyOnClick = procedure(Sender: TObject) of object;


In C++ muss ich eine Klasse angeben, zu dem der Methodenzeiger gehört:

C-/C++-Quelltext

1
typedef void(BasicComponent::*fcNotifyEvent)();


Wie bekomme ich es hin, einen deklarierten Methodenzeiger auch für andere Klassen verwenden zu können?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

18.06.2021, 13:57

Kannst du mal in einem konkreten Stück (nicht funktionierendem) Beispiel-Code zeigen, was du erreichen möchtest?

Timmyew

Treue Seele

  • »Timmyew« ist der Autor dieses Themas

Beiträge: 128

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

3

18.06.2021, 14:10

Ist etwas schwer das ganze darzustellen aber ich versuche es mal.

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
32
33
34
35
36
37
38
39
40
41
42
#include "Game.h"

Game::Game(){
    engine = new Engine();
    engine->Init(S_GAMETITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, B_FULLSCREEN);
    //SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1" );
}

Game::~Game(){
}

void Game::MainMenue(){
    btn_Test = engine->guiEngine->AddButton();
    btn_Test->SetCaption("Test");
    btn_Test->GetRect()->w = 200;
    btn_Test->GetRect()->h = 140;
    btn_Test->GetRect()->x = (WINDOW_WIDTH / 2) - (btn_Test->GetRect()->w / 2);
    btn_Test->GetRect()->y = (WINDOW_HEIGHT / 2) - (btn_Test->GetRect()->h / 2);
    btn_Test->_GetFont()->SetSize(30);
    btn_Test->_GetFont()->SetFontType(ftCalibri);

    //Hier soll das Event gesetzt werden
    btn_Test->SetOnClickEvent(click);

    //Menue loop
    while (engine->isRunning){

        engine->EventHandler();
        engine->Update();
        engine->Draw();

        //60 FPS
        SDL_Delay(16);
    }

    delete engine;
}

//Hier soll das Event aufgerufen werden, wenn der Button geklickt wird
void Game::click(){
    std::cout << "Button Test wurde geklickt" << std::endl;
}


Hier ist die Deklaration der Methode. Leider muss ich eine Klasse angeben und kann nicht frei wählen so wie in Delphi

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
32
33
#include "Sprite.h"
#include "Font.h"
#include <SDL.h>
#include <SDL_ttf.h>

#pragma once
class BasicComponent{
public:
    //####################### Deklaration des Methodentypes #######################
    typedef void(BasicComponent::*fcNotifyEvent)();
    BasicComponent();
    ~BasicComponent();

    virtual void Update();
    void EventHandler(SDL_Event* event);

    void _SetLayer(int value);
    void _SetSprite(Sprite* sprite);
    void _SetFont(Font* font);

    int _GetLayer();
    Sprite* _GetSprite();
    Font* _GetFont();

    void SetOnClickEvent(fcNotifyEvent* clickEvent);
    fcNotifyEvent* GetOnClickEvent();
private:
    Sprite* sprite = NULL;
    Font* font = NULL;

    int layer = 0;
    fcNotifyEvent* OnClick = nullptr;
};



Es handelt sich hierbei nicht wirklich um eine Engine, sondern um ein versuch ein kleines Spiel zu entwickeln.
Wollte es dieses mal etwas strukturierter angehen als beim letztem Spiel.
Seit bitte nicht zu hart zu mir, ich komme aus der Delphi Welt :P

4

18.06.2021, 15:07

Ich würde dafür std::function benutzen.

Das sieht dann ungefähr so aus:

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
#include <iostream>
#include <functional>

class Game
{
private:
    std::function<void(int)> clickEvent;
    
public:
    void SetClickEvent(std::function<void(int)> click)
    {
        clickEvent = click;
    }
    
    void TriggerEvent(int button)
    {
        if(clickEvent)
            clickEvent(button);
    }
};

int main()
{
    Game myGame;
    
    myGame.SetClickEvent( [&](int button) { std::cout<<button<<std::endl; } );
    
    myGame.TriggerEvent(2);
}


Ich hoffe ich kann dir weiter helfen.

Timmyew

Treue Seele

  • »Timmyew« ist der Autor dieses Themas

Beiträge: 128

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

5

18.06.2021, 18:35

Es hat mir aufjedenfal geholfen :)!
Hätte mir das aber gerade in c++ einfacher vorgestellt ?(

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

18.06.2021, 18:39

Das ist doch eigentlich schon ziemlich komfortabel.

Timmyew

Treue Seele

  • »Timmyew« ist der Autor dieses Themas

Beiträge: 128

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

7

18.06.2021, 20:03

Ich kenne es halt anders ^^.

Aber ich komme ja aus der Delphi-Welt ^^

FSA

Community-Fossil

  • Private Nachricht senden

8

19.06.2021, 04:52

Als Gedanke zur generellen Architektur: So wie du das löst kann man das machen, spricht auch erstmal nichts dagegen. Aber das ganze Event-Handling lässt sich besser skalieren und erweitern, wenn du nicht direkt events einer Klasse mit Funktionen einer anderen Klasse verknüpfst. Stattdessen könntest du eine (Warte-)Liste aus allen Events erstellen, ein Event-Handler verteilt die Events dann an die Consumer, an die das Event gerichtet ist. So hast du nur noch einzelne Objekte/Klassen, welche ein Event losschicken, dies in eine Warteliste kommt und dann von den Empfänger Objekten/Klassen verarbeitet wird. So in etwas funktioniert auch das Event-System in der WinAPI, kannst du dir mal angucken.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Timmyew

Treue Seele

  • »Timmyew« ist der Autor dieses Themas

Beiträge: 128

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

9

19.06.2021, 12:31

Mhm,

ich bin mir gerade nicht so sicher wie du das meinst.
Hättest du eine grafische Darstellung des Sachverhaltes?

Werbeanzeige