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

Volrath

Frischling

  • »Volrath« ist der Autor dieses Themas

Beiträge: 14

Beruf: Student Informatik

  • Private Nachricht senden

1

19.11.2004, 21:31

Funktionszeiger und Klassen

Ich habe ein Problem mit funktionszeigern:

Ich habe eine Algorithmusklasse, die neben anderen parameteren einen funktionszeiger übernimmt, um den Fortschritt zurückzumelden. Nun möchte ich dieser aber eine progress funktion aus einer anderen klasse übergeben. Allerdings lässt das der compiler nicht zu ...

Die Algo Klasse:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
class Algo{
public:
void execute((void)*progress(int)){
// bla

progress(0);
//blu

progress(1);
//....

}

}


Aufrufen der Funktion aus der Systemklasse:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class System{
public:
void func(){
_pAlgo.execute(proc);
}

private:
void proc(int i)
{
// Progressbar updaten

}

Algo _pAlgo;
}

Das geht so leider nicht, da der compiler Sestem::proc(int) nicht in proc(int) casten kann...

Mein Ansatz ist folgender, allerdings finde ich das das eher eine Notlösung ist.

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
System * _pSys = 0;

void wrap(int i)
{
  _pSys->proc(i);
}

class System{
public:
 System(){
  _pSys = this;
 }
 func{
  _pAlgo.execute(wrap(i));
 }

private:
 void proc(int i)
 {
  // Progressbar updaten

 }

 Algo _pAlgo;
}


Hatte schon jemand ein ähnliches Problem ? Wie hat er das gelöst ?

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

2

19.11.2004, 22:34

Zitat


Nun möchte ich dieser aber eine progress funktion aus einer anderen klasse übergeben. Allerdings lässt das der compiler nicht zu ...


Hast Du es mal mit typedef versucht?
"Games are algorithmic entertainment."

Volrath

Frischling

  • »Volrath« ist der Autor dieses Themas

Beiträge: 14

Beruf: Student Informatik

  • Private Nachricht senden

3

20.11.2004, 10:57

Hm, wie meinst du das konkret ? Gib mal ein Codebeispiel... ???

PD

unregistriert

4

20.11.2004, 11:47

Nich das ich mich mit Fubktionszeigern unheimlich auskennen würde aber müsste

C-/C++-Quelltext

1
_pAlgo.execute(proc(i));


nicht so lauten?

C-/C++-Quelltext

1
_pAlgo.execute(proc);


Nicht schlagen wenn ich jetzt falsch liege ^^

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

5

20.11.2004, 11:50

Z.B.:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef MYBOOL UpdateFunction(class CView *, long );

void CMdi_editView::OnUpdate(CView* pSender,LPARAM IHint,CObject* /*pHint*/)
{   UpdateFunction *pUpdateFunction;

    if(IHint==0L)
    {   CView::OnUpdate(pSender,0,NULL);
    }
    else
    {   pUpdateFunction=(UpdateFunction *)IHint;
        if(pUpdateFunction(this,1))
            CView::OnUpdate(pSender,0,NULL);
    }
}


Wenn OnUpdate vom System aufgerufen wird, ist der LPARAM ein Funktionszeiger, der NULL sein kann. Wenn er nicht NULL ist, wird die Callback-Funktion aufgerufen und je nach return Wert die CView OnUpdate FUnktion.
"Games are algorithmic entertainment."

Volrath

Frischling

  • »Volrath« ist der Autor dieses Themas

Beiträge: 14

Beruf: Student Informatik

  • Private Nachricht senden

6

20.11.2004, 12:59

Zitat von »"PD"«

Nich das ich mich mit Fubktionszeigern unheimlich auskennen würde aber müsste

C-/C++-Quelltext

1
_pAlgo.execute(proc(i));


nicht so lauten?

C-/C++-Quelltext

1
_pAlgo.execute(proc);


Nicht schlagen wenn ich jetzt falsch liege ^^



Ja, stimmt :-) Tippfehler meinerseits. Habe aber schon das gemeint ... (Korrigiere es im ersten Beitrag)

7

22.11.2004, 13:06

Also...du must unterscheiden zwischen einer Funktion und einer Methode.

Funktionszeiger:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef void (*FUNC)(int);

void run(FUNC func, int i)
{
   func(i);
}

void foo(int i)
{
   ....
}

void process()
{
   run(foo, 100);
   run(foo, 200);
}


Ein Methoden-Zeiger ist allerdings was ganz anderes.

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
class System;
typedef void (System::*METHOD)(int);

class Algo
{
public:
   void execute(System* system, METHOD method)
   {
       (system->*method)(0);
       (system->*method)(1);
       ....
   }
};

class System
{
public:
   void run()
   {
       algo_->execute(this, proc);
   }

private:
   void proc(int i)
   {
       ...
   }

private:
   Algo* algo_;
};


Du kannst keine Methode aufrufen ohne eine Instanz einer Klasse zu haben. Das klappt nicht.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Volrath

Frischling

  • »Volrath« ist der Autor dieses Themas

Beiträge: 14

Beruf: Student Informatik

  • Private Nachricht senden

8

22.11.2004, 19:47

Zitat von »"DragonMaster"«

Also...du must unterscheiden zwischen einer Funktion und einer Methode.

Du kannst keine Methode aufrufen ohne eine Instanz einer Klasse zu haben. Das klappt nicht.


Klingt eigentlich logisch, wenn man mal darüber nachdenkt :-)

Dann werde ich wohl die Lösung mit der globalen Variable für die Instanz belassen, weil die AlgoKlasse steckt in einer DLL die das Hauptprogramm natürlich nicht kennt (und somit auch die System Klasse nicht)

Danke für die Hilfe

Werbeanzeige