QObject und *parent Zeiger



  • Wenn ich das richtig verstanden habe, dann erbe ich von QObject wenn ich Funktionalitaet wie Signals und Slots in meiner Klasse bereitstellen moechte. Wenn ich solch eine Klasse per Creator generieren lasse, dann wird im Konstruktor auch immer ein QObject *parent mit aufgefuehrt.

    Wenn meine Klasse aber kein neues Widget oder so sein soll, brauche ich diesen Zeiger ja gar nicht, oder doch? Kann ich ihn dann einfach aus der Konstruktor-Parameterliste raus nehmen?

    Also so:

    class A : public QObject
    {
        Q_OBJECT
    
    public:
        A(int foo, QObject *parent = 0); // anstelle so, 
        A(int foo);                      // halt so hier?
    
    signals:
    
    public slots:
    
    };
    


  • Ja, kannst du natürlich machen. Ich bin mir aber nicht sicher, ob du das richtig verstanden hast. Den parent Zeiger braucht man für die Speicherverwaltung. Wenn ein QObject gelöscht wird, werden auch alle QObjects gelöscht, die das als parent haben. Wenn du das bei dieser konkreten Klasse nicht brauchst oder nicht willst, kannst du das natürlich weglassen.


  • Mod

    Das ist eine recht schwierige Frage, wenn man berücksichtigt, dass ein QObject mit Parent Zeiger mit new angelegt sein muss (da dass Parent es evtl. mit delete löscht).

    Daher wäre es sauberer, den Konstruktor ohne Zeiger public zu machen, und den mit private. Eine Erzeugung des Objekts mit Parent-Zeiger wäre dann nur über eine Create Methode möglich.



  • An die Speicherveraltung habe ich gar nicht gedacht, automatisches Aufraeumen ist natuerlich immer toll.

    Kann man also sagen, dass bei jedem Konstruktor das QObject * parent sicherheitshalber mit dazu gehoert?



  • CppNeuland schrieb:

    Kann man also sagen, dass bei jedem Konstruktor das QObject * parent sicherheitshalber mit dazu gehoert?

    Nein, hat phlox81 ja geschrieben. In C++ ist es oft besser, Objekte auf dem Stack und nicht auf dem Heap anzulegen. Dann werden die sowieso automatisch zerstört, wenn der Scope verlassen wird. Das musst du also abwägen.


  • Mod

    CppNeuland schrieb:

    An die Speicherveraltung habe ich gar nicht gedacht, automatisches Aufraeumen ist natuerlich immer toll.

    Kann man also sagen, dass bei jedem Konstruktor das QObject * parent sicherheitshalber mit dazu gehoert?

    Nein! Was ich meinte, ist dass eigentlich vom Interface eine Implementierung so aussehen könnte:

    class MyObject : public QObject
    {
    Q_OBJECT
    MyObject(int i, QObject* parent=0);
    public:
    MyObject(int i);
    static QObject* create(int i, QObject* parent){return new MyObject(i,parent);}
    };
    

    Damit wird sicher gestellt, dass ein Objekt welches ein Parent hat, mit new angelegt wird.



  • Ok, ich glaube ich verstehe. Da der Konstruktor private ist, kann ich nicht einfach durch MyObject instanz(42, & einQbject); ein Objekt anlegen, sondern muss dann den Umweg ueber create gehen, welches dann wieder ein Objekt auf dem Heap per new erzeugt.

    Wenn ich eine Klasse von QObject erben lasse, die wirklich nur den Signal/Slot-Mechanismuss braucht, kann ich dann das parent nicht einfach weglassen?



  • Wenn ich eine Klasse von QObject erben lasse, die wirklich nur den Signal/Slot-Mechanismuss braucht, kann ich dann das parent nicht einfach weglassen?

    Nein !
    Der QT Mechanismus bedingt, das Objecte die den SIgnal / Slot Mechanismus verwenden, von QObject abgeleitet sind ! (Q_OBJECT Macro ! das funzt imho dann nicht).

    Wobei nicht unbedingt erzwungen wird, das QObject Ableitungen aufn Freestore erzeugt werden muessen.

    Beispiel:

    QFileDialog diagFiles(this);
    int ir = diagFiles.exec();
    

    ....
    Sowas mach ich zum beispiel recht häufig.
    Das funktioniert natürlich nur so lange, wie der Parent das Object ueberlebt.
    WIrd das parent vor dem auf dem stack erzeugten child destruiert, krachts natürlich ^^

    BTW, der Signal/Slot mechanismus klingt toll. blüht aber in verbindung mit autodelete mechanismen (QObject) richtig auf.

    Aber das hat auch Nachteile. Lose Kopplung und GC's sind auch nicht die Domäne von C/C++. Wer sowas "Ohne Not" freiwillig verwendet, sollte überlegen ob er nicht lieber Java programmieren will ^^
    Wobei GUI in dem Falle eindeutig unter "Not" fällt 🙂

    Ciao ...


Log in to reply