提问者:小点点

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


我目前正在使用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上运行代码,程序在两种情况下都能工作。 我一头雾水,实在想不出问题出在哪里。


共1个答案

匿名用户

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就存在。 这种做法虽然略显繁琐,但也更加防弹。