Important: Please read the Qt Code of Conduct -

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;


    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
    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

    explicit Game(QWidget *parent = 0);

    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

    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) :
    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");
    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.
    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.

    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