Je veux faire une structure de données pour accéder à des chaînes de deux manières:
Ma première idée utilise deux cartes pour chaque méthode, mais elle conduit à la duplication des données: p> Je cherche une meilleure façon, quelque chose comme ceci: p> mais cela ne peut pas m'aider (au moins je ne sais pas comment le faire), car la recherche dans une carte doit connaître l'identifiant et le nom ensemble . Comment puis-je définir une structure de puits de classes QT pour atteindre mon objectif? P> pas de bibliothèques externes, mais qt em> p> p> P>
3 Réponses :
Que diriez-vous:
QString data = accessById[nameIdMap[the_name]];
+1 pour élaborer un bit de la mémoire un peu, mais notez que qstring code> est implicitement partagé sous la hotte afin que la double recherche vs. la mémoire peut ne pas être aussi claire une victoire car elle pourrait être avec d'autres Mise en œuvre de string: doc.qt.nokia.com/latest/implicite-shaing.html
@Masoudm. qpair code> est seulement un ajustement ici si une clé que vous souhaitiez avoir (1, "foo") code>, (2, "foo") code> , (1, "bar") code> etc. Carte pour différentes valeurs. Si vous êtes intéressé par des langues qui sont basées sur une correspondance de modèle efficace pour des clés génériques comme (1, *) code> ou (*, "foo") code> Ils sont là-bas ... mais qpair code> dans un qmap code> in c ++ ne fonctionne pas de cette façon.
QT n'a pas autant de soucis pour la duplication des données que de nombreuses autres bibliothèques de classe, en raison de "partage implicite": p>
http://doc.qt.nokia.com/latest/Implicit- Sharing.html P>
La liste des classes qui ont cette propriété (qui incluent http://fr.wikipedia.org/wiki/copy-on-write < / a> p>
http://doc.qt.nokia.com/latest/qshareddApoinTer. HTML # Détails P>
Pour résumer: Si vous avez un QString de 10 000 caractères et l'affectez-le à une autre variable qstring, vous ne paierez pas encore 10 000 caractères de stockage (sauf si vous ne modifiez pas les données de chaîne de l'une des deux instances). Néanmoins, même une poignée Qquing en lecture seule est un peu plus grosse qu'un qstring code>) est couverte dans ce lien. Il y a des aides à créer vos propres classes qui utilisent également une stratégie de copie-écriture également: P>
int code>. Cela dépend de votre scénario si cette différence de taille est importante contre le compromis de vitesse de plusieurs recherches, comme dans la stratégie offerte par @juho. P>
+1: points bien pour moi. OK, comment puis-je mettre les qstrings à deux cartes que partage implicitement code> s'applique à eux?
Comme indiqué par le terme "implicite", cela fonctionne simplement sans que vous fassiez faire quelque chose de spécial. Chaque fois que vous effectuez une mission qstring (y compris comme une clé ou une valeur sur une carte), l'affectation ne fera pas une copie des données de chaîne sous-jacentes. Chaque nouveau QQstring copié par la valeur sera simplement un pointeur sur les données partagées ... jusqu'à quelqu'un, quelque part, écrit à leur instance. Au moment de la rédaction, les données sont dupliquées. Tout cela se produit sous une manière thread-sûre dans les coulisses.
Donc, si j'écris qstring a = "bonjour"; code> et qstring b = "bonjour"; code> alors a code> B code > Fait référence à un bloc de données partagé?
Eh bien, cela pourrait ... mais si c'était le cas, cela n'aurait rien à voir avec QT, mais plutôt une caractéristique du compilateur appelé «mise en commun constant» ou «interne de chaîne» que vous pouvez enquêter si vous le souhaitez. Le cas est plus sur qstring a = "bonjour"; code> et qstring b = a; code>, qui ne nécessite pas de chaîne d'exécution se compare pour prendre des décisions sur la gestion de la mémoire ...
Remarque: En regardant les sources QT, il n'ya pas de vérification pour voir si le pointeur de code char * code> est identique sur plusieurs appels, votre version de l'exemple A / B serait donc définitivement attribuer des données distinctes. ..ven si le compilateur a mis en commun les constantes et a passé la même adresse à deux fois.
Vous pouvez utiliser boost bimap qui créera une carte bidirectionnelle entre l'identifiant et le nom. boost::bimap<int, QString> idNameBimap;
Boost MultiDex est exactement ce que vous cherchez pour.