【发布时间】:2013-07-12 20:51:04
【问题描述】:
我有一个名为Controller 的类,在其中,我有一个名为Button 的类。一个Controller 包含多个不同类型的Button 实例(例如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
按钮类型是ints,我希望能够将某些按钮类型ints 与指向这些特定类型的Button 实例的指针相关联。
为了跟踪这种关联,我使用std::map<int, Controller::Button*>,我将typedef 转换为buttonmap_t。
当我创建新的Button 实例(在Controller 构造函数中)时,Button 构造函数将这些Buttons 的类型注册到映射中。
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;
}
然后我创建一个全局Controller 对象,并定义main()。
main.cpp
#include <iostream>
#include "controller.h"
Controller controller;
int main(int argc, const char * argv[])
{
std::cout << "running..." << std::endl;
return 0;
}
根据我编译源代码的顺序,程序要么运行良好,要么触发分段错误:
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
后一种情况似乎是在正确初始化之前尝试使用地图,这导致了段错误。当我使用 Xcode 进行调试时,调试器在“__tree”中停止,因为 std::map 正在调用 __insert_node_at(),它会抛出 EXC_BAD_ACCESS(code=1, address=0x0)。调用堆栈显示这是由第一个 Button 实例调用 map[type] = this; 触发的。
所以,这是我的多部分问题:
- 为什么编译顺序会导致这种情况发生?
- 有没有办法实现这种
int到Button*的映射不受 编译顺序? - 如果有,是什么?
理想情况下,我仍然希望将所有 Controller- 和 Button 相关代码放在单独的 controller.* 文件中。
这似乎与以下问题有些相关(但不完全相同):
【问题讨论】:
-
附加说明,您可能希望将 .h 文件中的代码放在编译器指令中,该指令只编译一次。使用 ifndef 会有所帮助。
-
谢谢。为简洁起见,我已将其删除,但我只是将它们重新添加。
标签: c++ segmentation-fault stdmap