[英]Why can't I define a object of class(which inherited another class) outside the main function?
I am currently working with VS15 using the fltk library.我目前正在使用 fltk 库使用 VS15。 When I try to create an object of my class (which inherits Fl_Double_Window) outside the main function the program crashed.
当我尝试在主 function 之外创建我的 class(继承 Fl_Double_Window)的 object 时,程序崩溃了。
#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();
}
However, everything works properly when I create an object of class Fl_Double_Window directly (again outside the main function):但是,当我直接创建 class Fl_Double_Window 的 object 时,一切正常(同样在主函数之外):
#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();
}
The guy I downloaded the code from run the code on Ubuntu using C++11, and the program works in both cases.我下载代码的那个人使用 C++11 在 Ubuntu 上运行代码,该程序在这两种情况下都有效。 I'm confused and I really can't figure out what the problem is.
我很困惑,我真的无法弄清楚问题是什么。
You are getting a crash because you've put show (as mentioned by @bruno) in the constructor.您正在崩溃,因为您已将 show(如@bruno 所述)放入构造函数中。 If you take show out of the constructor and put it in main, you won't get the crash that you are seeing but the title will be incorrect for the reasons that @Sam Varshavchik has mentioned.
如果您从构造函数中取出 show 并将其放入 main 中,您将不会看到您看到的崩溃,但由于@Sam Varshavchik 提到的原因,标题将不正确。
struct MyWindow :Fl_Double_Window {
MyWindow(const std::string& s)
: Fl_Double_Window(10, 10, 500, 500) // 1) Do not set the title here
, caption(s) // 2) Take a copy of the title
{
// 3) Set the title here
this->copy_label(caption.c_str());
color(FL_BLACK);
// 4) Remove show from constructor
// show();
}
// 5) Declare caption - see Sam's solution
std::string caption;
};
MyWindow window("Special");
int main()
{
// 6) Move show here
window.show();
return Fl::run();
}
MyWindow(string s)
A constructor is not much different from a function.构造函数与 function 没有太大区别。
s
is a parameter to the constructor. s
是构造函数的参数。 Once the constructor returns, s
gets destroyed.一旦构造函数返回,
s
就会被销毁。
:Fl_Double_Window(10, 10, 500, 500, s.c_str()){
c_str()
returns a pointer to s
's contents, and passes it to the superclass's constructor. c_str()
返回指向s
内容的指针,并将其传递给超类的构造函数。 However because s
will get destroyed, any further usage of that pointer becomes undefined behavior, and a likely crash.但是,因为
s
将被破坏,所以对该指针的任何进一步使用都将成为未定义的行为,并且可能会崩溃。 Which is what's obviously happening.这显然是正在发生的事情。
The solution is slightly complicated.解决方案有点复杂。 This requires a delicate juggling act if you still wish to inherit from
FL_Double_Window
:如果您仍然希望从
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();
}
};
This juggles the order in which things get constructed and destroyed so that the s_name
class member continues to exist as long as FL_DoubleWindow exists.这会调整事物的构造和销毁顺序,以便只要 FL_DoubleWindow 存在,
s_name
class 成员就会继续存在。
There's also the (much) easier option of passing in a reference, but then you will have to ensure that the referenced std::string
exists as long as the window object exists.还有(更)更简单的传递引用的选项,但是只要 window object 存在,您就必须确保引用的
std::string
存在。 This approach, although slightly cumbersome, is also more bulletproof.这种方法虽然有点麻烦,但也更防弹。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.