Frage

In QT versuche ich, mein eigenes QWIDget aufzubauen, damit alles aufgrund des Speichermanagements und anderer Dinge gut funktionieren sollte. Aber ich kann mit Zeigern, Haufen und Stapel nicht gut gut machen. Ich habe mein Widget MyWidget, das eine Qlist mit einigen Objekten hat. Ich kann nicht herausfinden, wie ich alles richtig einrichten kann.

Sie können meinen Code unten sehen und ich habe einige Fragen dazu:

  1. Die Instace -Variablenliste wird auf dem Haufen erstellt. Wäre es besser, sie auf dem Stapel zu erstellen?

  2. In meiner Liste habe ich Hinweise, wäre es besser, das Objekt auf dem Stapel zu erstellen und es der Liste anzuhängen? (Damit ich überhaupt keine Zeiger in der Liste habe)

  3. Wenn ich die Objekte an die Liste angehängt habe, erhalten sie die Liste automatisch als Eltern? Wenn ich also die Liste lösche, werden alle Objekte in der Liste gelöscht?

  4. Die für jede Schleife, die ich verwenden möchte, funktioniert nicht. Ich habe "ein Zeiger-/Array -Typ für diese Operation anstelle von 'int' erwartet."

  5. In meinem Code möchte ich andere Widgets erstellen, die das Objekt aus der Liste als Parameter nutzen. Ist es der richtige Weg, es so zu tun, wie ich es getan habe? Die Instanzmethode von MyotherWidget sieht so aus: MyotherWidget (myObject *myObject, Qwidget *Eltern)

Danke für Ihre Hilfe! Ich bin neu bei QT und C ++, also wäre es großartig, wenn Sie mich in die richtige Richtung führen könnten. Wie kann ich dies auf die richtige Weise einrichten, um es einfach zu machen, keine Speicherlecks zu erhalten und bei Bedarf so wenig Speicher zu verwenden. Wie würden Sie dasselbe einrichten?

Dies ist mein Code:

Mywidget.h:

class MyWidget : public QWidget
{
Q_OBJECT

public:
    MyWidget(QWidget *parent = 0);
    ~MyWidget();

private:
    QList<MyObject*> *list;
};

Mywidget.cpp:

MyWidget::MyWidget(QWidget *parent)
{
    ui.setupUi(this);

    list = new QList<MyObject*>();
    for (int i = 0; i<10; i++) 
    {
        MyObject *myObject = new MyObject("Hello",this);
        list->append(myObject);
    }

    foreach(MyObject *myObject, list)
    {
        //Lets say I want to create other widgets here and that they takes a MyObject as a parameter
        MyOtherWidget *myOtherWidget = new MyOtherWidget(myObject,this);
    }

}

MyWidget::~MyWidget(){
    delete list;
}
War es hilfreich?

Lösung

Ad.1. Die Lebensdauer der Liste sollte mit der Lebensdauer der MyWidget -Instanz übereinstimmen, sodass Sie die Liste sicher auf dem Stapel erstellen können.

Ad.2. Sie könnten das tun, aber die MyObject -Klasse müsste einen Standardkonstruktor, einen Kopierkonstruktor und einen Zuordnungsbetreiber haben (siehe http://doc.trolltech.com/4.6/containers.html#container-classes für Details).

Ad.3. Das Eigentum des Objekts wird nicht im Anhang übertragen. Genau wie STL -Container ruft QT -Container nicht auf gespeicherte Zeiger auf. So löschen Sie alle in Qlist (oder anderen QT -Container) gespeicherten Zeiger, Sie können QDeletAll (Liste) verwenden. Denken Sie daran, dass Sie dies wahrscheinlich nicht in dem Code tun möchten, den Sie gepostet haben: Sie übergeben MyWidget -Zeiger an MyObject Constructor und ich gehe davon aus, dass er dann als QOBJECT -Elternteil verwendet wird. So werden alle QObjects gelöscht, wenn MyWidget gelöscht wird.

Ad.4. Das zweite Argument von Foreach Makro sollte ein Container sein, kein Zeiger auf den Container. Sie sollten also foreach (myObject *obj, *liste) anrufen, wenn Ihre Listenvariable ein Zeiger auf Qlist ist.

Ad.5. Es sollte Ihnen gut gehen, solange MyotherWidget das übergebene MyObject nicht löscht (da das MyWidget bereits ein Elternteil von MyObject ist und Sie das gleiche Objekt zweimal löschen würden).

Es ist eine grobe Vereinfachung, aber Sie sollten versuchen, Ihren Code so zu schreiben, dass Sie überhaupt nicht löschen müssen. Erstellen Sie Sachen auf dem Stapel oder verlassen Sie sich auf QT-Eltern-Kinder-Mechanismus (dh Eltern löschen ihre Kinder). Später möchten Sie vielleicht über intelligente Zeiger lesen (QsharedPointer, qScopedPointer usw.).

BEARBEITEN:

Ob der Elternteil von MyObject festgelegt ist oder nicht, hängt von dem ab, was Sie im MyObject -Konstruktor tun. Wenn Sie übergeordnete Argument an den QObject Constructor weitergeben, sieht der MyObject -Konstruktor so aus:

MyObject(const QString &text, QObject *parent = 0) : QObject(parent)
{
// more code...
}

Der übergeordnete Elternteil wird festgelegt, da es im QObject Constructor erfolgt, der aufgrund des Code ": QObject (übergeordnet)" aufgerufen wird. Was ist, wenn Sie dieses Fragment nicht haben? Da das MyObject QObject erbt und Sie nicht angeben gelöscht.

Ich würde versuchen, die Eltern explizit durch setParent -Methode festzulegen - für grundlegende Anwendungsfälle sollte das Einstellen von Eltern im Konstruktor ausreichen.

Versuchen Sie, die korrekte Terminologie (nicht "Instanzmethode", sondern "Konstruktor") zu verwenden, QT -Dokumentation zu lesen, den gesunden Menschenverstand zu verwenden und nicht zu glauben, dass etwas automatisch durchgeführt wird. Der übergeordnete Elternteil wird nicht "automatisch" festgelegt, nur weil Sie ein Argument "übergeordnet" nennen - es ist festgelegt, da es einen Code gibt, der es im QObject -Konstruktor tut, und es ist in Ihrer Verantwortung, Pass für ordnungsgemäße übergeordnete übergeordnete Konstruktor in den Klassen zu rufen das Erbe QObject.

Andere Tipps

Ja, das Problem ist, dass Sie das Objekt Ihrer Liste löschen, aber nicht die Elemente!

Ich schlage vor, Sie sehen sich an:

QList<Employee *> list;
list.append(new Employee("Blackpool", "Stephen"));
list.append(new Employee("Twist", "Oliver"));

qDeleteAll(list.begin(), list.end());
list.clear();

Weitere Informationen hier

Ich würde auch fragen, ob Sie wirklich einen Zeiger auf Ihre Liste brauchen. Sie könnten einfach ein einfaches haben:

QList<MyObject*> list;

Deshalb haben Sie ein weniger mögliches Speicherleck!

Hoffe das hilft ein bisschen!

Bearbeiten :
3. Ihre MyObject -Objekte haben "diese" als Eltern. Die Liste nimmt die Objektbesitz nicht an, wenn Sie sich mit Zeigern befassen.
4. Für die Schleife sollten Sie vielleicht Iteratoren in Betracht ziehen, schauen Sie sich hier an qthelp: //com.trolltech.qt.460/qdoc/qlist.html.

Sie müssen die Kinder -Widgets nicht in einer Liste speichern, solange Sie sie Eltern des aktuellen Widgets machen. (Normalerweise erstellen Sie Ihre Widgets auf dem Stapel mit neu).

QT verfügt über eine automatische CleanUp-Funktion. Wenn ein Widget alle untergeordneten Widgets entfernt wird (Widgets, deren Eltern das Widget ist, das entfernt wird), werden sie entfernt.

Das einzige, was Sie also sicherstellen müssen (insbesondere für temporäre Popup -Widgets), um das Widget "Popup" zu löschen/zu entfernen oder Ihr Popup -Widget zu nennen.

Das wars.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top