2017-08-03 4 views
0

Wie ich verstehe die quicksort, wenn das Schlurfen der Mitglieder mit der Kopie Ctor geschehen ist, wirst du ziemlich durch das, was O (n ln n enttäuscht sein) bedeutet wirklich. So entschied ich mich qSort mitQt: qSort ohne die Kopie Konstruktor

QList<QObject> mylist; //Yes, I know this isn't feasible, I just wanted to find where the copy ctor is being used 
qSort(list); 

zu testen und wurde getroffen mit denen

'QObject :: QObject (const QObject &)' ist privat

Fehler. Von dem, was ich sagen kann, beginnt das Problem mit der begin() Methode, denn wenn ich

list.begin(); 

der Compiler Fehler zeigt habe, dass diese qlist.h Linie irgendwie die Kopie Ctor versucht, zu verwenden:

inline void detach() { if (d->ref != 1) detach_helper(); } 

Ich weiß, ich könnte die Mitglieder der Liste Zeiger machen, dann implementieren Sie die lessThan Funktion, aber das ist nicht sehr bequem für diese Code-Basis. Also, wie kann ich vermeiden, die Kopie ctor, wenn qSort arbeitet auf einer Liste von Objekten?

Ich verwende Qt 4.8 unter Linux 64-Bit und 32-Bit.

+1

Ich verwende nicht qt, aber Sie könnten eine Reihe von Indizes von 0 bis zur maximalen Anzahl der Elemente einrichten - 1. Dann sortieren Sie die Indizes anstelle Ihrer Liste und verwenden Sie diese, um die Daten zu referenzieren. – PaulMcKenzie

+0

@PaulMcKenzie Ist das besser als mit Zeigern? – Opux

+0

Ja, es ist "besser" als Zeiger, da es keine Zeiger benötigt. Ich könnte eine Antwort posten, aber es wird darauf ausgerichtet sein, 'std :: sort' und' vector' zu verwenden, nicht Qt (aber das gleiche Prinzip würde gelten, würde ich glauben). – PaulMcKenzie

Antwort

0

Ich werde einen Stich machen, da ich kein Qt-Benutzer bin.

Wenn Sie eine Liste von Objekten sortieren müssen, die nicht kopiert werden können, oder wenn der Kopieraspekt teuer ist, können Sie im Allgemeinen eine Liste von Indizes anstelle der Daten sortieren und nach der Sortierung Verwenden Sie die Indexliste, um auf die Daten zuzugreifen.

Nach der Dokumentation für Qt qSort, so etwas wie dies funktionieren kann die Methode oben mit:

int doSomething() 
{ 
    QList<QObject> myList; 
    //... 
    QVector<int> index(myList.size()); 
    for (int i = 0; i < myList.size(); ++i) index[i] = i; 
    qSort(index.begin(), index.end(), [](int n1, int n2) { return myList[n1] < myList[n2];}); 
} 

Sobald dies erledigt ist, greifen Sie auf die sortierte myList Behälter thusly:

myList[index[0]]; // First item 
myList[index[1]]; // second item 
... 

Hinweis : Ich gehe davon aus, dass qSort eine Lambda-Funktion als drittes Argument akzeptiert. Wenn Probleme auftreten, können Sie ein Funktionsobjekt verwenden.

+0

Das ist im Wesentlichen das gleiche wie das Sortieren von Zeigern, wobei die Zeiger Indizes sind, außer dass es weniger Indirektion mit Zeigern gibt. – MofX

0

QObject hat weder einen Kopierkonstruktor noch einen Zuweisungsoperator. Das ist Absicht.

http://doc.qt.io/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator

So einfach kann man nicht qSort einen Behälter mit QObject s oder abgeleiteten Klassen, zumindest nicht in C++ vor C++ 11. Sie könnten versuchen, C++ 11-Unterstützung (oder höher) in Ihrem Compiler einschalten (und stellen Sie sicher, dass Ihre Qt-Bibliotheken auch damit kompiliert werden); Wenn die Qt-Leute so gut wie üblich sind, benutzen sie in diesem Fall move semantics.

Else mit Zeigern oder vielleicht einer der Qt-Zeiger-Klassen wie QSharedPointer wäre ein gültiger Weg zu gehen.Und Sie werden einen lessThan Operator oder eine Funktion sowieso benötigen, wenn Sie nicht möchten, dass die Reihenfolge nach Speicheradresse ist.

Verwandte Themen