I have a class called Controller , inside which I have a class called Button . A Controller contains several Button instances for different types (e.g. button_type_a , button_type_b ).
Controller.h
#ifndef __controller__ #define __controller__ class Controller { public: class Button { public: Button(int type = -1); private: int type; }; Controller(); Button A; Button B; Button X; Button Y; }; #endif
The types of buttons are int s, and I would like to be able to associate a specific type of button int with pointers to Button instances of these specific types.
To track this connection, I use std::map<int, Controller::Button*> , which I typedef is equal to buttonmap_t .
When I create new Button instances (in the Controller constructor), the Button constructor registers the types of these Button with the map.
Controller.cpp
#include "controller.h" #include <map> typedef std::map<int, Controller::Button*> buttonmap_t; buttonmap_t map; Controller::Controller() : A(0), B(1), X(2), Y(3) { } Controller::Button::Button(int type) : type(type) { map[type] = this; }
Then I create a global Controller object, and I define main() .
<b> main.cpp
#include <iostream> #include "controller.h" Controller controller; int main(int argc, const char * argv[]) { std::cout << "running..." << std::endl; return 0; }
Depending on the order in which I compile the sources, the program either works fine or causes a segmentation error:
apogee:MapTest$ gcc controller.cpp main.cpp -o maptest -lstdc++ apogee:MapTest$ ./maptest running... apogee:MapTest$ gcc main.cpp controller.cpp -o maptest -lstdc++ apogee:MapTest$ ./maptest Segmentation fault: 11
It seems that the latter case is trying to use the card before it was properly initialized and caused a seg error. When I debug Xcode, the debugger stops at "__tree" when std::map calls __insert_node_at() , which EXC_BAD_ACCESS(code=1, address=0x0) . The call stack shows that this is caused by the first Button instance calling map[type] = this; .
So here is my multi-part question:
- Why does the compilation order cause this?
- Is there a way to achieve this kind of display
int to Button* , which is not affected by the compile order? - If so, what is it?
Ideally, I would still like to have all the Controller - and Button related code in separate controller files. *.
This seems to be somewhat related to (but not quite the same) the following questions: