首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我不能在main函数之外定义class的对象(它继承了另一个类)?

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

Stack Overflow用户
提问于 2020-06-27 20:15:30
回答 2查看 79关注 0票数 1

我目前正在使用fltk库来处理VS15。当我试图在main函数之外创建我的类(继承Fl_Double_Window)的一个对象时,程序崩溃了。

代码语言:javascript
运行
复制
#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函数之外),一切都可以正常工作:

代码语言:javascript
运行
复制
#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上运行的,程序在这两种情况下都能运行。我很困惑,我真的不知道问题出在哪里。

EN

回答 2

Stack Overflow用户

发布于 2020-08-04 13:33:03

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

代码语言:javascript
运行
复制
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();
}
票数 2
EN

Stack Overflow用户

发布于 2020-06-27 20:34:29

代码语言:javascript
运行
复制
MyWindow(string s)

构造函数与函数没有太大的不同。s是构造函数的参数。一旦构造函数返回,s就会被销毁。

代码语言:javascript
运行
复制
                  :Fl_Double_Window(10, 10, 500, 500, s.c_str()){

c_str()返回一个指向s内容的指针,并将其传递给超类的构造函数。然而,由于s将被销毁,任何进一步使用该指针的行为都将成为未定义的行为,并可能崩溃。这显然就是正在发生的事情。

解决方案有点复杂。如果您仍然希望从FL_Double_Window继承,则需要巧妙地处理这一点

代码语言:javascript
运行
复制
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对象存在,就必须确保引用的window一直存在。这种方法虽然有点麻烦,但也更加防弹。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62609899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档