简体   繁体   English

为什么我不能在主 function 之外定义一个类的 object(继承了另一个类)?

[英]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.

相关问题 为什么我不能在类之外定义一个返回类型为“指向结构的指针”的函数? - why can't i define a function of return type 'pointer to struct' outside of class? 无法定义类函数OUTSIDE类 - Can't define class functions OUTSIDE class 为什么我不能在主函数中更改类的公共变量 - why i can't change a public variable of a class in the main function 继承的类可以覆盖另一个继承的类的虚函数吗? - Can an inherited class override another inherited class' virtual function? 为什么朋友函数不能访问继承类的私有变量? - Why can't a friend function access the private variables of an inherited class? 我可以创建一个包含另一个类的对象的定义构造函数吗? - Can i make a define constructor which contains an object from another class? 为什么我不能将此成员函数作为另一个类的朋友? - Why can't I make this member function friend of another class? 如果要从另一个翻译单元链接某个成员函数,为什么不能在该类中定义该成员函数? - Why can I not define a member function in a class if that function is to be linked from another translation unit? 为什么我调用抽象 class 时不能使用继承的 class? - Why can't I use the inherited class when I called abstract class? 为什么我不能在另一个函数中定义一个函数? - Why can't I define a function inside another function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM