Compile Problem-Function Pointers

Hi! I have a problem and I don't know what is the solution
Technically it's solved if any of you knows how you can compile this:
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 <iostream>
using namespace std;
struct Button{
	void (*onclick)();
	void (*onover)();
	void (*onleave)();
	Button(void (*o)(),void (*c)(),void (*l)()){
		onclick=c;
		onover=o;
		onleave=l;
	}
};
struct EBar{
	Button *goup,*godown;
	EBar(){
		init();
	}
	void update();
	void clicku();
	void overu();
	void clickd();
	void overd();
	void leaved();
	void leaveu();
	void init();
};
void EBar::init(){
	goup=new Button(overu,clicku,leaveu);
	godown=new Button(overd,clickd,leaved);
}
int main(){
 return 0;   
}

I'm looking for a way which every EBar has its own Button!
The problem you have is that the callbacks have to be static so you have two options.

If you only have one EBar then just make each function static.

If you have more than one EBar you still need static callbacks but those callbacks have to be able to call an 'instance' specific callback so you will need something like this

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

#include <iostream>
using namespace std;

struct EBar;

// Generic callback
struct Callback{
   Callback(EBar *ptr, void(*f)(EBar *))
   :owner(ptr), func(f)
   {
   }
   
   void(*func)(EBar *);

   EBar *owner;
   
   void cb();
};

// Button holds pointers to callback rather than function pointers
struct Button{
        Callback *onclick;
	Callback *onover;
	Callback *onleave;

	Button(Callback *click, Callback *over, Callback *leave){
		onclick=click;
		onover=over;
		onleave=leave;
	}
	void click_callback();
};

void Button::click_callback()
{
   onclick->cb();
}

struct EBar{
	Button *goup,*godown;
	EBar(){
		init();
	}
	void update();
	static void static_clicku(EBar *instance);
	static void static_overu(EBar *instance);
	static void static_clickd(EBar *instance);
	static void static_overd(EBar *instance);
	static void static_leaved(EBar *instance);
	static void static_leaveu(EBar *instance);
	void init();
	void clicku(){};
	void overu(){};
	void clickd(){};
	void overd(){};
	void leaved(){};
	void leaveu(){};
};

// Static functions only purpose is to call 'instance' callbacks
void EBar::static_clicku(EBar *instance)
{
      instance->clicku();
}
void EBar::static_clickd(EBar *instance)
{
      instance->clickd();
}
void EBar::static_overu(EBar *instance)
{
      instance->overu();
}
void EBar::static_overd(EBar *instance)
{
      instance->overd();
}
void EBar::static_leaveu(EBar *instance)
{
      instance->leaveu();
}
void EBar::static_leaved(EBar *instance)
{
      instance->leaved();
}

// Create a Callback instance for each callback needed
void EBar::init(){
        Callback *ou = new Callback(this, &static_overu);
	Callback *cu = new Callback(this, &static_clicku);
	Callback *lu = new Callback(this, &static_leaveu);
	Callback *od = new Callback(this, &static_overd);
	Callback *cd = new Callback(this, &static_clickd);
	Callback *ld = new Callback(this, &static_leaved);
	goup=new Button(ou,cu,lu);
	godown=new Button(od,cd,ld);
}

// Single function for callback
void Callback::cb()
   {
       func(owner);  
   }

int main(){
 return 0;   
}


I hope it's fairly self explanatory, if not post your questions

Bertha
Thank you for your really useful post.
:D
Glad to help
boost::function and boost::bind can help avoid the need for static functions.
(see http://www.boost.org).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <boost/function.hpp>
#include <boost/bind.hpp>

struct Button {
    typedef boost::function<void(void)> Callback;
    Button( const Callback& click, const Callback& over, const Callback& leave ) :
       click( click ), over( over ), leave( leave ) {}
    Callback click, over, leave;
};

struct EBar {
    Button* goup, godown;
    EBar() : goup( new Button( boost::bind( &EBar::click, this ),
                                                boost::bind( &EBar::over, this ),
                                                boost::bind( &EBar::leave, this ) ) ),
                 godown( /* ... */ ) {}

    void click();
    void over();
    void leave();
};

Topic archived. No new replies allowed.