我正在开发一个GUI项目,由于某种原因,以下调用add_gfx_object()会使我的程序崩溃。
MainMenuState::MainMenuState(Demo& demo)
: m_start_button{new Button(Sol::Rectangle{Sol::Vector{10, 10}, 100, 30},
[] {std::cout << "clicked";})}
{
demo.add_gfx_object(m_start_button); // <-- crashes program
}
这里列出了Demo类中的相关代码。
class Demo : public Sol::Application
{
public:
StateMachine<Demo> fsm;
Demo();
~Demo();
//...
void add_gfx_object(const GraphicalEntity* const obj) {m_draw_list.push_back(obj);}
private:
std::list<const GraphicalEntity*> m_draw_list;
void draw_objects();
};
奇怪的是,对add_gfx_object()的调用不会导致程序崩溃。
Demo::Demo()
: Application("Demo", 800, 600, false), fsm(*this, new MainMenuState(*this))
{
add_gfx_object(new Button(Sol::Rectangle(), []{})); // <-- does not crash program
}
在这些示例中用nullptr替换Button指针会产生相同的结果。尽管我想提供有关该问题的其他信息,但我无法做到。谁能解释为什么我的程序不断崩溃?
答案 0 :(得分:0)
这是您创建对象的顺序。
在Application
的构造函数列表和成员Demo
的构造函数中调用Demo
的基类(fsm
)的构造函数。在Demo
的构造过程中,首先构造基类,然后只有Demo
的其他成员按照它们被声明的顺序构建 - 首先fsm
并且只有在列表m_draw_list
。
但是对于fsm
的构造函数,您尝试将调用的指针结果传递给传递给最后MainMenuState
的{{1}}构造函数,并且是部分构造的*this
没有列表的对象。因此,在调用Demo
时,您的程序崩溃的意图是使用未初始化的列表。
您必须考虑如何组织代码并防止对象创建的循环依赖。您可能需要将一些参数传递给已经完全创建的对象,例如在构造函数的主体内部,其中所有成员都已构造,包括列表,如“工作”示例中所示。在这种情况下,您也可以在公开MainMenuState(Demo& demo)
之前声明私人列表m_draw_list
。