2015-08-26 8 views
5

Mein spezifisches Problem ist, dass ich ein QMultiHash<Foo,Bar*>private Mitglied haben, und ich möchte Zugriff auf die Werte des Hash bieten, aber zu const Versionen der Produkte und erklärte:Convert (Qt) Container von Objekten in Container const Objekte effizient?

QList<const Bar*> getBars(Foo f) const; 

Ist gibt es eine sauberere/effizientere Möglichkeit, die Artikel innerhalb eines Qt-Containers als die hässliche/ineffiziente Erstellung eines neuen Containers mit const-Elementen und Kopieren von Zeigern aus der Quelle (QMultiHash<K,V>::values() in diesem Fall) "zu konstituieren"?

Ich fürchte, die Antwort könnte "nein" sein, aber ich wollte sicherstellen, dass ich nicht einige Qt/C++ (03) Syntax Magie zu tun, um das zu tun.

+1

Siehe http://stackoverflow.com/questions/10265695/treat-vectorint-as-vectorconst-int-without-copying-c0x Ich kenne keine Lösung (außer vielleicht einen riesigen hässlichen Hack), aber ist ein 'for' loop so eine große Sache?Es ist einfach, Zeiger zu kopieren, ich bezweifle, dass es sich auf Ihre Leistung auswirken wird - es sei denn, die 'QList' ist riesig und Sie haben sehr hohe Leistungsanforderungen. – Armaghast

+0

Überprüfen Sie auch http://stackoverflow.com/questions/2102244/vector-and-const für den Grund. – Armaghast

+0

In diesem speziellen Fall ist es keine große Sache (und ich habe es so umgesetzt). Aber es verstört meinen Sinn für Stil, und in anderen Fällen in meiner Anwendung (interaktive Datenvisualisierung) könnte ich interaktive UI-Operationen auf Containern von ~ 1000-10000s Chart Glyph-Objekten durchführen müssen, wobei ich die Glyph-Objekte inspiziere, aber nicht verändere ohne die UI zu verzögern, nur um einen Container mit Const-Zeigern zu erhalten. – eclarkso

Antwort

0

Es gibt zwei Möglichkeiten. Der offensichtliche Weg, den Sie erwähnen, ist C++ 11 zu verwenden und es selbst in QList<const Bar*> zu konvertieren.

QList<const Bar*> getList() const 
{ 
    QList<const Bar*> list; 

    for(Bar *b : m_List) //where m_List is your private memebr QList<Bar*> 
     list << b; 

    return list; 
} 

Der andere Weg ist die QList sich const QList<Bar*> zu konvertieren, die „magische Weise“ durch Rücksendung der Liste aus einer konstanten Funktion zum Beispiel durchgeführt werden kann:

const QList<Bar*> getList() const 
{ 
    return m_List; //where m_List is your private memebr QList<Bar*> 
} 

Welches auf Ihrem hängt zu verwenden braucht. Nach dem, was Sie beschreiben, müssen Sie die Elemente überprüfen, ohne sie zu ändern. Das hört sich so an, dass Sie die modifizierbare Liste gar nicht benötigen. Die erste Variante klingt schon wie ein Overkill. Sie wollen const Bar* vermutlich, weil Sie nicht möchten, dass es sich durch Zufall ändert, wenn Sie das Element überprüfen. Um alle Elemente zu untersuchen zum Beispiel könnten Sie tun (Hinzufügen const automatisch für jedes Element):

for(const Bar *b : myObject->getList()) 
    //do only const stuff with b 

Wenn Sie einen wirklich guten Grund haben für die Rückkehr QList<const Bar*> wie, dass Sie die Liste müssen modifizierbar sein, ist es nicht wert, die Ärger und Leistungseinbruch. Sie können Bar * mit const einschränken, wenn Sie selbst darauf zugreifen, indem Sie C++ 11 for in einer Weise verwenden, die ich beschrieben habe, oder indem Sie konstante Iteratoren verwenden. Von dem, was ich sammle, würde ich empfehlen, das zu verwenden, anstatt (möglicherweise große) Listenwerte in const umzuwandeln.

Und ein letzter Tipp, wenn Sie Ihre Listen wirklich riesig sind, und Sie müssen jeden Tropfen der Leistung berücksichtigen:

const QList<Bar*> &getList() const 

Die implizite gemeinsame Nutzung von Qt tut dies im vorherigen Code-Snippet auf seine eigene Ich glaube aber das stellt sicher, dass die Liste bei der Inspektion niemals kopiert oder geändert wird.

+0

Beachten Sie, dass mein tatsächliches Mitglied ein QMultiHash ist, und was ich Const-Zugriff bieten möchte, ist die Liste der Werte von QMultiHash :: values ​​(). Daher ist die letzte const-Referenz keine Option. Beachten Sie auch, dass ein wichtiger Grund für die Bereitstellung eines solchen Accessors für die Korrektheit der Korrektheit ist; Außerdem würde ich es vorziehen, mich nicht auf die guten Seiten von mir selbst oder anderen zu verlassen, um angemessen auf die Liste (über const iterators et al.) zuzugreifen. – eclarkso

+0

@eclarkso In diesem Fall besteht Ihre einzige Möglichkeit darin, eine solche Liste selbst zu erstellen. Selbst wenn es eine Funktion gäbe, die es für Sie erstellen würde, würde es fast dasselbe tun - eine neue Liste mit const Elementen erstellen. Wie auch immer, benutze C++ 11, um es zu tun, da es der schnellste verfügbare Weg ist. Wenn Sie nicht zu Leistungsproblemen kommen, weil Ihre Inspektion zu lange dauert, weil die Liste zu groß ist (und die Konvertierung zu lange dauert), sollte das kein Problem darstellen. Wenn die Leistung zu einem Problem wird, müssen Sie wahrscheinlich Ihre Prioritäten oder Ihr Design überdenken. Viel Glück! – Resurrection

0

Keine effektive Möglichkeit, Objekte im bestehenden Array zu "konstituieren". Aber wenn Sie wirklich eine Liste von Zeigern speichern. Kann schnell sein, nicht "const" Zeiger auf "const" Zeiger in einem einfachen Zyklus zu konvertieren ?! (Ie. make neue Liste) Zweite Lösung ist make "const" Objekte in der Liste zunächst, wenn Sie diese Liste füllen. Und der dritte Weg ist, eigene Klassen Ihrer Liste zu machen, was nur "const" Referenz oder Iterator zu gespeicherten Elementen zurückgeben kann.

+0

Ich hoffe, Sie verstehen mich ohne Codebeispiele. Bitte lass es mich wissen, wenn nicht. Ich werde mehr erklären. – stanislav888

Verwandte Themen