|
initialising static member |
William Labbett
Member #4,486
March 2004
|
hi, In my code I want to initialise the static member variable bitmap_generator
1class Map_Section {
2
3 static ALLEGRO_BITMAP *(*bitmap_generator[NUM_BITMAP_GENERATING_FUNCTIONS])( void );
4
5
6
7
8 public:
9
10 GRID_SQUARE **gs;
11
12 ALLEGRO_BITMAP **features_bitmaps;
13
14 BITMAP_LIST *shadows_list;
15
16 unsigned char **cdata;
17
18 int w, h;
19
20 Map_Section ( const char *frd_filename, const char *map_bitmap, const char *shadows_list_filename );
21
22 Map_Section();
23
24};
25
26
27
28//I'm trying to do it here :
29
30const ALLEGRO_BITMAP *(*bitmap_generator[NUM_BITMAP_GENERATING_FUNCTIONS])( void ) =
31
32{
33 get_grass_recangle
34}
...but I need to make sure it's recognised as the member of Map_Section How would I do this ?
|
jmasterx
Member #11,410
October 2009
|
Usually initializing static members is done like this: //in hpp class foo { private: static int i; }; //in cpp int foo::i = 0; for an array = {0,0,0,0} should work Agui GUI API -> https://github.com/jmasterx/Agui |
William Labbett
Member #4,486
March 2004
|
yeah, reason I'm asking is because I'm not sure where to put the Map_Section:: e.g. should it go here : const ALLEGRO_BITMAP *(Map_Section ::*bitmap_generator[NUM_BITMAP_GENERATING_FUNCTIONS])( void ) = (which doesn't look right) ?
|
jmasterx
Member #11,410
October 2009
|
I found this: also it should not be const in the cpp since it is not const in your hpp Agui GUI API -> https://github.com/jmasterx/Agui |
William Labbett
Member #4,486
March 2004
|
Thanks for that. I've tried it and it works. Thanks for spotting the unnecessary const
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
In C++ you don't need to use (void) as the parameter list either, a simple () will do fine. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
William Labbett
Member #4,486
March 2004
|
Thanks. 1class Map_Section {
2
3 static ALLEGRO_BITMAP *(*bitmap_generator)();
4
5
6
7
8 public:
9
10 GRID_SQUARE **gs;
11
12 ALLEGRO_BITMAP **features_bitmaps;
13
14 BITMAP_LIST *shadows_list;
15
16 unsigned char **cdata;
17
18 int w, h;
19
20 Map_Section ( const char *frd_filename, const char *map_bitmap, const char *shadows_list_filename );
21
22 Map_Section();
23
24};
25
26
27
28ALLEGRO_BITMAP *(Map_Section::*bitmap_generator)( void ) =
29{
30 get_grass_rectangle
31};
I get an error for this code : C:\game_project_jan2011\rabbitsgame>mingw32-make C:\game_project_jan2011\rabbitsgame>PAUSE obviously something's wrong. Any ideas ?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
I think that this : ALLEGRO_BITMAP *(Map_Section::*bitmap_generator)( void ) = {get_grass_rectangle}; should be this : ALLEGRO_BITMAP* (*Map_Section::bitmap_generator)() = get_grass_rectangle; Give that a whirl... compiler said: error: 'show_through_bitmaps' was not declared in this scope This means you probably forgot to include the classes scope in the definition of the function. class A { private : int member; public : void DoStuff(); }; void DoStuff() {member = 5;}// error, member not declared in this scope void A::DoStuff() {member = 5;}// fine
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
anonymous
Member #8025
November 2006
|
int (Sample::*ptr2)(int, int); This should be a pointer-to-member-function type. What you seem to want is an array of pointers to free functions. It appears that the class name should go right in front of the variable name. ALLEGRO_BITMAP (*Map_Section::bitmap_generator[NUM_BITMAP_GENERATING_FUNCTIONS])( void ) I dropped one pointer as I don't see what exactly that would be for. Anyway, as always, to avoid going crazy with the declaration syntax, you'd bring in typedefs. 1struct X {
2 typedef int (*fun_type)();
3 static fun_type functions[2];
4};
5
6int foo() { return 1;}
7int bar() { return 2;}
8
9//I'm trying to do it here :
10
11X::fun_type X::functions[2] =
12
13{
14 &foo, &bar
15};
16
17int main()
18{
19 return X::functions[0]();
20}
|
William Labbett
Member #4,486
March 2004
|
Edgar Reynaldo said: Give that a whirl... Thanks, that worked. I thought it looked wrong. I suppose such an initialisation always has to be classname::variablename /* edit */ @anonymous Do you really have to take the address of those functions ? ie &foo and &bar ? Aren't foo and bar already pointer values ?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
William Labbett said: Do you really have to take the address of those functions ? No. Either way works, you can use the names themselves, or their address. Similarly, you can call a function pointer by using a dereference, or by using the name itself : 1#include <cstdio>
2
3void foo(int a) {
4 printf("%i\n" , a);
5}
6
7int main(int argc , char** argv) {
8 void (*foopointer)(int) = foo;
9 void (*foopointer)(int) = &foo;
10
11 (*foopointer)(10);
12 foopointer(12);
13
14 return 0;
15}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
William Labbett
Member #4,486
March 2004
|
wow, interesting. Just to be clear about something else : anonymous said: int (Sample::*ptr2)(int, int); This should be a pointer-to-member-function type. So that's valid C++ but what kind declaration would it have to have in the class itself ?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
William Labbett said: what kind declaration would it have to have in the class itself ?
1
2class Test {
3public :
4 typedef void (Test::* VoidTestMemberVoidFunc) ();// The space after the * is important
5
6private :
7 VoidTestMemberVoidFunc vtmvf;
8
9 void Foo() {printf("Foo.\n");}
10 void Bar() {printf("Bar.\n");}
11
12public :
13 void UseFoo() {vtmvf = &Test::Foo;}// You must use & here
14 void UseBar() {vtmvf = &Test::Bar;}// You must use & here
15
16 void FooBar() {(this->*vtmvf)();}
17
18 Test() : vtmvf(&Test::Foo) {}
19};
20
21int main(int argc , char** argv) {
22 Test t;
23 t.FooBar();
24 t.UseBar();
25 t.FooBar();
26
27 return 0;
28}
So a pointer to a member function is like this : ReturnType (ClassName::* FunctionPointerName)(Parameter List); and you would set and call it like this : ClassName Object; ClassName* ObjectPointer = &Object; FunctionPointerName = &ClassName::FunctionName; (Object.*FunctionPointerName)(Parameters); (ObjectPointer->*FunctionPointerName)(Parameters); All that said, I had to do a little testing before I got it right, and I've also never had a use for this kind of obscure C++ yet. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
William Labbett
Member #4,486
March 2004
|
brilliant. Think I just need the static array of function pointers for the moment. Thanks once more, for clearing that up.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Not to be intrusive, but what are you going to use a static array of member function pointers for? It seems like there should be a simpler way... My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
William Labbett
Member #4,486
March 2004
|
Edgar Reynaldo said: but what are you going to use a static array of member function pointers for? I'm using a static array of function pointers. (note the difference). It's a long story. I've got a file which has lots of what I call feature representations in. Each one has a bunch of data : a name for a png bitmap which is the feature itself. Now, if the type is SHOW_THROUGH_GENERATED then the feature has no bitmap associated Instead, the ALLEGRO_BITMAP * in that array is assigned to by calling a function which returns an ALLEGRO_BITMAP *. In this case, since the png bitmap filename data for this feature isn't used to load a bitmap, it's used instead to specify which function to call. So for example, one of the features is a grass bitmap which is generated with some code and is got by calling get_grass_bitmap(). So the program sees it's type is SHOW_THROUGH_GENERATED, looks at the string normally used to load a bitmap, sees it's "GRASS" and passes this to a function which returns an index for the array of function pointers which will be the function get_grass_bitmap(). Manage to make any sense of that?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
William Labbett said: I'm using a static array of function pointers. (note the difference). Noted, I just wasn't sure because you were asking about member function pointers. William Labbett said: Instead, the ALLEGRO_BITMAP * in that array is assigned to by calling a function which returns an ALLEGRO_BITMAP *. In this case, since the png bitmap filename data for this feature isn't used to load a bitmap, it's used instead to specify which function to call. Okay, I see what you are doing now. It makes sense. So your ALLEGRO_BITMAP* functions are for creating and drawing a new bitmap, right? Question - are you using a std::map<string , ALLEGRO_BITMAP*(*)()> to return the function pointer? std::map implements a binary search for you, and that way you don't have to mess around with a linear search for the entry that matches your string. 1typedef ALLEGRO_BITMAP* (*TILEMAKERFUNC)();
2
3ALLEGRO_BITMAP* MakeGrassTile() {/*...*/}
4ALLEGRO_BITMAP* MakeSandTile() {/*...*/}
5ALLEGRO_BITMAP* MakeWaterTile() {/*...*/}
6
7map<string , TILEMAKERFUNC> tilefuncmap;
8
9tilefuncmap["Grass"] = MakeGrassTile;
10tilefuncmap["Sand"] = MakeSandTile;
11tilefuncmap["Water"] = MakeWaterTile;
12
13ALLEGRO_BITMAP* MakeTile(string tilename) {
14 map<string , TILEMAKERFUNC>::iterator it = tilefuncmap.find(tilename);
15 if (it != tilefuncmap.end()) {
16 return (it->second)();
17// return (tilefuncmap[tilename])();
18 }
19 return 0;
20}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
William Labbett
Member #4,486
March 2004
|
Edgar Reynaldo said: Question - are you using a std::map<string , ALLEGRO_BITMAP*(*)()> to return the function pointer? Er.. no. For some reason I thought maps were going to be hard to grasp and I thought I probably aught to wait a while until I've learnt a heap of other stuff first. ..but obviously you think I should be able to do it now and I think I get the gist of what your code does. Thanks for that... I'll have a go.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
If you get stuck, here's a good guide to the STL map class. Use is fairly simple : 1// declare a map
2map<KEY_TYPE , VALUE_TYPE , optional_key_comparison_functor> mapname;
3
4// Add entry to the map
5mapname[KEY] = VALUE;
6
7// Get entry from the map
8VALUE = mapname[KEY];
9
10// Modify entry in the map
11mapname[KEY] *= 2;
12
13// Iterate over all the values of the map :
14typedef map<KEY_TYPE , VALUE_TYPE> MY_MAP_TYPE;// to simplify typing
15
16for (MY_MAP_TYPE::iterator it = mapname.begin() ; it != mapname.end() ; ++it) {
17 KEY_TYPE key = it->first;
18 VALUE_TYPE value = it->second;
19 cout << "Key '" << key << "' , value = " << value << endl;
20}
The optional key comparison function is only needed if the key_type specified does not have key_type::operator<(const key_type& k) implemented (or the global operator< implemented). Also, the page I linked to earlier has an example of a comparison object at the beginning of the page. One thing to be aware of is if you access the map using a key that isn't in the map, you will get an object of type VALUE_TYPE constructed using the default constructor. That's why you use the map member function find : map<KEY_TYPE , VALUE_TYPE>::iterator it = mapname.find(key_type); if (it == mapname.end()) {/* Not found */} else { /// use the iterator it } Other useful functions are clear() and erase(iterator). My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|