为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?

Why can't I define a object of class(which inherited another class) outside the main function?

本文关键字:一个 对象 另一个 继承 不能 函数 为什么 定义      更新时间:2023-10-16

我目前正在使用 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 上运行代码,该程序在这两种情况下都可以工作。 我很困惑,我真的不知道问题是什么。

你遇到了崩溃,因为你在构造函数中放置了 show(如 @bruno 所述(。 如果你把 show 从构造函数中取出并把它放在 main 中,你不会得到你所看到的崩溃,但由于 Varshavchik @Sam提到的原因,标题将不正确。

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)

构造函数与函数没有太大区别。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存在。这种方法虽然略显繁琐,但也更加防弹。

相关文章: