我目前正在使用fltk库处理VS15。 当我试图在main函数之外创建我的类(它继承了Fl_Double_Window)的对象时,程序崩溃了。
#include"FL/Fl.H"
#include"FL/Fl_Double_Window.h"
#include"FL/Fl_draw.h"
#include"FL/Fl_Slider.H"
#include"FL/Fl_Input.H"
#include"FL/Fl_Button.H"
#include"FL/Fl_Text_Display.H"
#include<string>
struct MyWindow :Fl_Double_Window {
MyWindow(string s):Fl_Double_Window(10, 10, 500, 500, s.c_str()){
color(FL_BLACK);
show();
}
};
MyWindow window("Special");
int main()
{
return Fl::run();
}
但是,当我直接创建类Fl_Double_Window的对象(同样是在main函数之外)时,一切都正常工作:
#include"FL/Fl.H"
#include"FL/Fl_Double_Window.h"
#include"FL/Fl_draw.h"
#include"FL/Fl_Slider.H"
#include"FL/Fl_Input.H"
#include"FL/Fl_Button.H"
#include"FL/Fl_Text_Display.H"
#include<string>
string name = "Special";
Fl_Double_Window window(10, 10, 500, 500, name.c_str());
int main()
{
window.color(FL_BLACK);
window.show();
return Fl::run();
}
我下载的那个人用C++11在Ubuntu上运行代码,程序在两种情况下都能工作。 我一头雾水,实在想不出问题出在哪里。
MyWindow(string s)
构造函数与函数没有多大区别。 S
是构造函数的参数。 一旦构造函数返回,s
就会被销毁。
:Fl_Double_Window(10, 10, 500, 500, s.c_str()){
c_str()
返回指向S
内容的指针,并将其传递给超类的构造函数。 但是,由于s
将被破坏,因此对该指针的任何进一步使用都将成为未定义的行为,并可能导致崩溃。 这显然是正在发生的事情。
解决方案略显复杂。 如果您仍希望继承FL_Double_Window
,则需要进行微妙的变通操作:
struct my_data {
string s_name;
my_data(string s) : s_name(s)
{
}
};
struct MyWindow :my_data, Fl_Double_Window {
MyWindow(string s): my_data(s),
Fl_Double_Window(10, 10, 500, 500, this->s_name.c_str()){
color(FL_BLACK);
show();
}
};
这就改变了构造和销毁的顺序,这样只要FL_DoubleWindow存在,S_name
类成员就会继续存在。
还有一个简单得多的选项是传入引用,但是您必须确保只要窗口对象存在,所引用的std::string
就存在。 这种做法虽然略显繁琐,但也更加防弹。