Frustration in Qt: MyClass obj; makes my application refuse to show up. MyClass *obj = new MyClass; works fine.



  • To be honest, my title might be a little confusing.

    I'm experimenting with Qt, making a desktop application that allows the user to "play" with a list of movies. Play as in add, edit or remove movies.

    So I've made a Movie class of my own, for it to be used in conjuction with the other custom classes.

    Here's movie:

    @#ifndef MOVIE_H
    #define MOVIE_H

    #include <QObject>
    #include <QStringList>

    class Movie
    {
    int movieID;
    QString movieTitle;
    QString movieGenre;
    QString movieDirector;
    int movieDuration;
    QStringList movieCast;
    int movieYear;
    int three_dim;

    public:
    Movie();
    ~Movie();

    void setID(int given_ID);
    void setTitle(QString given_title);
    void setGenre(QString given_genre);
    void setDirector(QString given_director);
    void setDuration(int given_duration);
    void addCast(QString given_cast);
    void setYear(int given_year);
    bool is3D();
    
    int getID();
    QString getTitle();
    

    };

    #endif // MOVIE_H@

    Please excuse the lack of some getters.
    The constructor of Movie, Movie(), just sets all the variables for non-valid-for-my-program values. 0 for every int, "" for every QString.

    So I'm also making a Game class, which looks like this and is the "beef" of the application:

    @#ifndef GAME_H
    #define GAME_H

    #include <QWidget>
    #include <QtGui>
    #include <movie.h>
    #include <theater.h>
    #include <screening.h>

    class Game : public QWidget
    {
    private:
    Q_OBJECT
    int screen; //Defines what we display to the player
    QVBoxLayout *layout; //Layout of the whole game widget
    QList<Movie> movieList; //The list of the player's movies

    public:
    explicit Game(QWidget *parent = 0);
    ~Game();

    void initialiseGame();
    
    int getScreen();             //HELPERS
    void clearLayout(QLayout *local_layout);
    void setScreen(int num); //Sets our screen to a specific value
    
    void showScreen();        //According to what our screen is, we show the appropriate output and choices
    

    signals:
    int screenChanged(int newScreen); //Might help with bugfixing

    private slots:
    void quit();
    void newGame();
    void editMovies();
    void toMainMenu();
    void screenBack();
    void screenForward();

    public slots:

    };

    #endif // GAME_H
    @

    The constructor of Game looks like this:

    @Game::Game(QWidget *parent) :
    QWidget(parent)
    {
    layout = new QVBoxLayout(this); //Layout initialised before setScreen() is called.
    movieList = QList<Movie>(); //This should initialise our movieList to an empty one.
    //movieList->clear(); //In case there's junk in it, we can always uncomment this line.

    Movie space_odyssey;                     //MARKER: Problem is here
    space_odyssey.setTitle("Space Odyssey");
    movieList.append(space_odyssey);
    
    
    setScreen(1);                                //Game starts!
    

    }@

    You might expect this constructor to go through. Nope.
    It won't allow the layout (which gets set-up through setScreen() and then shown in main() ) and, while goes through compilation, causes a "The program has unexpectedly finished." runtime.

    I've narrowed it down to the line
    @Movie space_odyssey;@
    as everything else goes through fine (tested through a lot of qWarning()s) and, when commented out, the program works fine.

    Anybody have any idea of what I am doing wrong? It's 3am and I have still not managed to have any [b]POSITIVE[/b] results.

    Note that if you do @Movie *space_odyssey;@ or @Movie *space_odyssey = new Movie();@ the program continues fine. But this has a problem of being a needless pointer and also something that my QList is not made to work with.

    If it matters, dears, my main looks like this:
    @int main(int argc, char *argv[])
    {
    QApplication TheaterManager(argc, argv);

    MainWindow *window = new MainWindow; //Our main window
    //Notepad *notepad = new Notepad;
    Game *game = new Game(window);       //The game itself, acts as a central widget
                                         //of our window. game.screen starts at 1.
    
    window->setCentralWidget(game);
    window->setMinimumSize(630,230);
    window->show();
    
    
    return TheaterManager.exec(&#41;;
    

    }@

    MainWindow is a currently completely plain QMainWindow subclass.


  • Moderators

    When you have
    @
    Movie space_odyssey; //MARKER: Problem is here
    @

    space_odyssey is created on the stack. As soon as the Game constructor exits (4 lines later) space_odyssey is destroyed.

    Using
    @
    Movie *space_odyssey = new Movie();
    @
    creates the object on the heap, and allows it to exist past the end of your destructor (although you should either make Game the parent of space_odyssey so that it cleans up after itself, or make the space_odyssey pointer a member variable so you can manually delete it in Game's destructor.

    It's not a "needless pointer." In fact, it's a very necessary pointer :)



  • What I do not understand is, why would a pointless stack object being created and being destroyed a few lines after affect the outcome of the program in the slightest?

    Would that imply that the problem is in the deconstructor of my Movie class?


  • Moderators

    Ah, I believe I misunderstood your original question/problem. Sorry.



  • Turns out it actually was... my deconstructor consisted of Movie::~Movie(){ delete this;} which would obviously malfunction in case of a non-pointer object.

    Thanks a lot, mlong.

    And I'll be damned if I don't thank you for your swift reply.


  • Moderators

    No problem, glad that it led to the right solution after all!

    Edit to add:

    You would never use
    @
    delete this;
    @

    in a destructor (or anywhere for that matter, typically.)

    Calling delete on an object is actually what causes the destructor to be called.



  • So by doing it I was causing an infinite loop, no?


  • Moderators

    Perhaps, but it's at best an undefined (and definitely undesirable) behavior.



  • When you create a child class in a parent class and try to delete the child class in the class itself, you will most definitely get a segfault. It is the parents job to mop that up.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.