<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://www.shadoware.org/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Shadoware.Org - Mot-clé - nokia</title>
  <link>http://www.shadoware.org/</link>
  <atom:link href="http://www.shadoware.org/index.php/feed/tag/nokia/rss2" rel="self" type="application/rss+xml"/>
  <description>Moi, mes idées, mes logiciels ...</description>
  <language>fr</language>
  <pubDate>Mon, 06 Feb 2012 15:38:11 +0100</pubDate>
  <copyright>Ulrich VANDENHEKKE</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>[C++/Qt] Performance de l'utilisation de QSharedPointer</title>
    <link>http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer</link>
    <guid isPermaLink="false">urn:md5:f477dcc0189d180d38c2a61076493790</guid>
    <pubDate>Tue, 25 Jan 2011 12:00:00 +0100</pubDate>
    <dc:creator>Ulrich Van Den Hekke</dc:creator>
        <category>Performances</category>
        <category>kde</category><category>nokia</category><category>performance</category><category>planet</category><category>qmake</category><category>qt</category><category>trolltech</category>    
    <description>&lt;h3&gt;Présentation&lt;/h3&gt;


&lt;p&gt;&lt;em&gt;Qt&lt;/em&gt; est un framework orienté objet écrit en C++ et permettant de faire des interfaces graphiques. Ce framework est utilisé par le projet &lt;em&gt;KDE&lt;/em&gt; depuis ses débuts pour en faire un environnement de bureau très complet.&lt;/p&gt;


&lt;p&gt;&lt;em&gt;Qt&lt;/em&gt; fournit un ensemble de pointeur &lt;em&gt;intelligent&lt;/em&gt;&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-1&quot; id=&quot;rev-pnote-628-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt; permettant de gérer plus facilement la mémoire. Le but est alors de ne plus avoir à supprimer des objets. La suppression se fera soit par un pointeur &lt;em&gt;intelligent&lt;/em&gt; soit par le système de hiérarchie d'objet existant en &lt;em&gt;Qt&lt;/em&gt; (l'objet père qui supprime l'ensemble des objets fils qui lui sont rattachés).&lt;/p&gt;


&lt;p&gt;&lt;em&gt;Qt&lt;/em&gt; propose l'ensemble des pointeurs &lt;em&gt;intelligents&lt;/em&gt; suivants:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.qt.nokia.com/4.6/qshareddatapointer.html&quot; hreflang=&quot;en&quot; title=&quot;Documentation Qt de QSharedDataPointer&quot;&gt;QSharedDataPointer&lt;/a&gt; / &lt;a href=&quot;http://doc.qt.nokia.com/4.6/qshareddata.html&quot; hreflang=&quot;en&quot; title=&quot;Documentation Qt de QSharedData&quot;&gt;QSharedData&lt;/a&gt;&amp;nbsp;: ces deux classes utilisées ensemble permettent d'écrire un objet avec partage implicite. Cela signifie que l'objet fonctionnera comme la classe &lt;em&gt;QString&lt;/em&gt;. Tant que l'objet est copié, passé en paramètre, .... l'objet n'est pas dupliqué (tous les objets pointes vers le même espace mémoire). Au moment où l'objet est modifié, l'objet est dupliqué. C'est ce qu'on appelle le COW&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-2&quot; id=&quot;rev-pnote-628-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.qt.nokia.com/4.6/qexplicitlyshareddatapointer.html&quot; hreflang=&quot;en&quot; title=&quot;Documentation Qt de QExplictlySharedDataPointer&quot;&gt;QExplictlySharedDataPointer&lt;/a&gt; / &lt;a href=&quot;http://doc.qt.nokia.com/4.6/qshareddata.html&quot; hreflang=&quot;en&quot; title=&quot;Documentation Qt de QSharedData&quot;&gt;QSharedData&lt;/a&gt;&amp;nbsp;: QExplicitlySharedDataPointer est une variante de QSharedDataPointer. Ce pointeur &lt;em&gt;intelligent&lt;/em&gt;, comme son nom l'indique, est détaché uniquement lorsque la méthode detach() est appelée explicitement. Cette classe permet de faire des objets qui fonctionnent comme des pointeurs mais qui sont utilisés sans la notion de pointeur (le *). La suppression des données partagées se fait donc quand tous les objets ne sont plus utilisés.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.qt.nokia.com/4.6/qscopedpointer.html&quot; hreflang=&quot;en&quot; title=&quot;Documentation Qt de QScopedPointer&quot;&gt;QScopedPointer&lt;/a&gt;&amp;nbsp;: Ce pointeur est le plus simple. Il permet de déclarer un pointeur sur le tas et s'occupe de la destruction de l'objet, lorsque le programme sort de la portée du bloc. Cela permet de ne plus se soucier de la libération du pointeur dans les cas d'erreur (exception, retour avant la fin de la fonction car le fichier n'a pu être ouvert, ...).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://doc.qt.nokia.com/4.6/qsharedpointer.html&quot; hreflang=&quot;en&quot; title=&quot;Documentation Qt de QSharedPointer&quot;&gt;QSharedPointer&lt;/a&gt;&amp;nbsp;: Le pointeur dont on parlera dans la suite de ce billet. Il permet de partager non plus des données (comme le fait QSharedData) mais de partager un pointeur&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-3&quot; id=&quot;rev-pnote-628-3&quot;&gt;3&lt;/a&gt;]&lt;/sup&gt;. Nous allons voir dans la suite du billet, comment simplement utiliser ce pointeur, et les performances de ce pointeur par rapport à un pointeur standard.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Sommaire&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#utilisation_qsharedpointer&quot;&gt;Utilisation de QSharedPointer&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#a_quoi_sert_il&quot;&gt;A quoi sert-il ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#comment_l_utiliser&quot;&gt;Comment l'utiliser ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#comment_utiliser_this&quot;&gt;Comment utiliser this&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#comment_eviter_les_references_circulaires&quot;&gt;Comment éviter les références circulaires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#utilisation_dans_les_applications_multi_thread&quot;&gt;Utilisation dans les applications multi-thread.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#utilisation_d_un_pool&quot;&gt;Utilisation d'un pool&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#benchmark&quot;&gt;Benchmark&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#code_source&quot;&gt;Code source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#le_jeu_de_test&quot;&gt;Le jeu de test&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#test_de_l_allocation&quot;&gt;Test de l'allocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#test_de_modification_d_une_donnee&quot;&gt;Test de Modification d'une donnée&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#test_d_affectation&quot;&gt;Test d'affectation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#test_de_destruction&quot;&gt;Test de destruction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#resultat_du_test&quot;&gt;Résultat du test&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-1&quot; id=&quot;pnote-628-1&quot;&gt;1&lt;/a&gt;] en anglais : smart-pointer&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-2&quot; id=&quot;pnote-628-2&quot;&gt;2&lt;/a&gt;] COW = Copy On Write&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-3&quot; id=&quot;pnote-628-3&quot;&gt;3&lt;/a&gt;] Ce pointeur est l'équivalent du pointeur &lt;em&gt;intelligent&lt;/em&gt; &lt;a href=&quot;http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/shared_ptr.htm&quot; hreflang=&quot;en&quot;&gt;boost::shared_ptr&lt;/a&gt; du projet &lt;a href=&quot;http://www.boost.org/&quot; hreflang=&quot;en&quot;&gt;Boost&lt;/a&gt;. Boost est une librairie qui ajoute beaucoup de facilité pour les programmes en C++, comme par exemple les smart-pointer dont certains seront inclus dans C++0x, ou de la boucle &lt;code&gt;std::for_each&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
    &lt;p&gt;&lt;a name=&quot;utilisation_qsharedpointer&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Utilisation de QSharedPointer&lt;/h3&gt;


&lt;p&gt;&lt;a name=&quot;a_quoi_sert_il&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;A quoi sert-il&amp;nbsp;?&lt;/h4&gt;


&lt;p&gt;L'objet &lt;code&gt;QSharedPointer&lt;/code&gt; fait partie des pointeurs &lt;em&gt;intelligents&lt;/em&gt;. Ces pointeurs permettent de gérer automatiquement la libération de la mémoire (plus besoin de faire &lt;code&gt;delete ptr;&lt;/code&gt; quand le pointeur n'est plus utilisé) tout en restant utilisable comme un pointeur normal.&lt;/p&gt;


&lt;p&gt;&lt;code&gt;QSharedPointer&lt;/code&gt; fonctionne par comptage de référence. Après la déclaration, à chaque affectation, on augmente le compteur de référence, lorsqu'on quitte la portée du bloc, on décrémente le compteur de référence. &lt;code&gt;QSharedPointer&lt;/code&gt; détruit donc automatiquement le pointeur quand il n'existe plus aucune référence vers ce pointeur. &lt;code&gt;QSharedPointer&lt;/code&gt; vient donc comme une encapsulation de notre pointeur.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qsharedpointer/QSharedPointer1.png&quot; alt=&quot;QSharedPointer1.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;QSharedPointer1.png, janv. 2011&quot; /&gt;&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;comment_l_utiliser&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Comment l'utiliser&amp;nbsp;?&lt;/h4&gt;


&lt;p&gt;La déclaration d'un pointeur en C, se fait en écrivant &lt;code&gt;MyObject*&lt;/code&gt;. La syntaxe en utilisant un QSharedPointer se fait en écrivant &lt;code&gt;QSharedPointer&amp;lt;MyObject&amp;gt;&lt;/code&gt;. Par la suite dans le programme, l'utilisation du pointeur &lt;code&gt;QSharedObject&lt;/code&gt; se fera de la même manière qu'un pointeur C. (Avec l'opérateur &lt;code&gt;-&amp;gt;&lt;/code&gt; pour appeler un membre, une méthode, ...) . Appelons dans la suite pointeur C, les pointeurs standards et &lt;code&gt;QSharedPointer&lt;/code&gt;, le pointeur intelligent.&lt;/p&gt;


&lt;p&gt;Afin d'éviter d'avoir un pointeur normal pouvant être supprimé à tout moment dans l'application, lors de l'utilisation de &lt;code&gt;QSharedPointer&lt;/code&gt;, il ne faut utiliser le pointeur C résultant du &lt;code&gt;new&lt;/code&gt; que pour la création du &lt;code&gt;QSharedPointer&lt;/code&gt;. On peut donc directement créer le &lt;code&gt;QSharedPointer&lt;/code&gt; en utilisant le constructeur &lt;code&gt;QSharedPointer ( T * ptr )&lt;/code&gt; qui prend en paramètre le pointeur C. C'est entre ces parenthèses que nous allons créer le pointeur C&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-1&quot; id=&quot;rev-pnote-628-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span style=&quot;color: #666666;&quot;&gt;// Création du pointeur intelligent à partir d'un pointeur normal.&lt;/span&gt;
  QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; MyObject&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span style=&quot;color: #666666;&quot;&gt;// Utilisation du pointeur intelligent comme un pointeur normal.&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    ptr&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;setMembre&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;maValeur&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  &lt;span style=&quot;color: #666666;&quot;&gt;// Appel d'une méthode utilisant ce pointeur&lt;/span&gt;
  maMethode&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Lorsque l'on quitte le bloc, si le comptage de référence tombe à 0, on supprime le pointeur. A l'intérieur de &lt;code&gt;maMethode()&lt;/code&gt; le nombre de référence sera passé à 2. Si la méthode utilise le pointeur mais ne l'assigne nul part, le nombre de référence devrait être retombé à 1 et donc ici sera décrémenté à 0.&lt;/p&gt;


&lt;p&gt;Si par contre, &lt;code&gt;maMethode()&lt;/code&gt; fait des opérations d'assignation de &lt;code&gt;ptr&lt;/code&gt; et conserve une copie, le comptage ne tombera pas à 0 tant que l'objet restera utilisé (assigné) ailleurs.&lt;/p&gt;


&lt;p&gt;Regardons un exemple de &lt;code&gt;maMethode()&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; maMethode&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  ptr&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;setMembre2&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;maValeur&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Au début du bloc, ici le comptage de référence est à 2 et sera décrémenté à la sortie de la méthode. On peut modifier les membres de &lt;code&gt;ptr&lt;/code&gt;, et dans ce cas pas de changement du comptage de référence.&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;this&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;monPtr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Au contraire, on peut également l'assigner à un autre objet. Dans ce cas le comptage de référence de cet objet passera à 3. A la sortie de la méthode il sera décrémenté et passera alors à 2. L'objet ne sera pas supprimé tant qu'on ne fera pas un &lt;code&gt;this-&amp;gt;monPtr.clear()&lt;/code&gt; ou que &lt;code&gt;this&lt;/code&gt; ne sera pas détruit.&lt;/p&gt;


&lt;p&gt;Si on veut garder une référence d'un pointeur mais qu'on ne souhaite pas que celle-ci incrémente le nombre de référence du &lt;code&gt;QSharedPointer&lt;/code&gt;, il est possible de créer un pointeur &lt;em&gt;faible&lt;/em&gt;. Ce pointeur passe par l'objet &lt;code&gt;QWeakPointer&lt;/code&gt;. Pour obtenir ce type de pointeur, il suffit de faire&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;QWeakPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptrW &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; ptr&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;toWeakRef &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;&lt;code&gt;ptrW&lt;/code&gt; n'incrémente donc pas le comptage de référence, cela signifie donc que le pointeur peut être détruit même si un objet &lt;code&gt;QWeakPointer&lt;/code&gt; existe. Il sera alors possible de faire un &lt;code&gt;ptrW.isNull()&lt;/code&gt; pour savoir si le pointeur est toujours valide. Si l'utilisateur a également besoin d'avoir accès à un membre de l'objet, il pourra le transformer en &lt;code&gt;QSharedPointer&lt;/code&gt; avant de l'utiliser sauf si le pointeur est &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr2 &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; ptrW&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;toStrongRef &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt; 
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
   ptr&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;maMethodePtr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Il faut tester que &lt;code&gt;ptr2&lt;/code&gt; est encore valide, car tant que la transformation du pointeur &lt;em&gt;faible&lt;/em&gt; vers le &lt;code&gt;QSharedPointer&lt;/code&gt; n'a pas encore été fait, il est possible que le nombre de référence vers l'objet soit tombé à 0 et qu'il ait été supprimé.&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;comment_utiliser_this&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Comment utiliser &lt;code&gt;this&lt;/code&gt;&lt;/h4&gt;


&lt;p&gt;Un des points peu pratique de l'utilisation de &lt;code&gt;QSharedPointer&lt;/code&gt; est que le comptage de référence ne fonctionne pas si plusieurs &lt;code&gt;QSharedPointer&lt;/code&gt; pointent vers le même objet mais ont tous été créés à partir du pointeur C. Prenons par exemple, le cas suivant&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;MyObject &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt; ptr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; MyObject&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr1 &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; QSharedPointer&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr2 &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; QSharedPointer&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Le problème d'écrire ces lignes ainsi, et que pour  &lt;code&gt;ptr1&lt;/code&gt; comme pour &lt;code&gt;ptr2&lt;/code&gt;, l'objet n'est référencé qu'une fois. Ainsi le premier qui tombera à 0 détruira l'objet, alors que l'autre pourrait encore l'utiliser. Il faut donc écrire les choses comme suite&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qsharedpointer/QSharedPointer2.png&quot; alt=&quot;QSharedPointer2.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;QSharedPointer2.png, janv. 2011&quot; /&gt;&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr1 &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; QSharedPointer&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; MyObject&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr2 &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; ptr1&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Ainsi &lt;code&gt;ptr1&lt;/code&gt; et &lt;code&gt;ptr2&lt;/code&gt; ont bien chacun connaissance de l'existence de l'autre. Cela contraint donc à remplacer toutes les déclarations du type &lt;code&gt;MyObject*&lt;/code&gt; par &lt;code&gt;QSharedPointer&amp;lt;MyObject&amp;gt;&lt;/code&gt;. Ceci est donc à faire dans les paramètres des méthodes, dans les membres, dans la déclaration des variables locales, ... . On ne peut donc plus utiliser le pointeur C &lt;code&gt;MyObject*&lt;/code&gt; directement, mais seulement au travers de &lt;code&gt;QSharedPointer&lt;/code&gt; ou de &lt;code&gt;QWeakPointer&lt;/code&gt;.&lt;/p&gt;


&lt;p&gt;Cela commence à poser problème lors de l'utilisation de &lt;code&gt;this&lt;/code&gt; dans un objet. Imaginons une méthode d'un objet mettant à jour des membres fils avec en paramètre le père. Nous aurions alors tendance à écrire ceci&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; Object2&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;setParent&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; parent&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
...
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
....
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; MyObject&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;setMember&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;Object2 &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt; obj&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  _membre &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; obj&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;obj&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    obj&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;setParent&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Ceci ne marchera pas car on créerait un nouvel objet &lt;code&gt;QSharedPointer&lt;/code&gt; commençant son comptage de référence à 1, alors que nous en avons déjà au moins un autre pointant vers notre instance&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-2&quot; id=&quot;rev-pnote-628-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;. &lt;code&gt;MyObject&lt;/code&gt; pourrait alors être détruit alors qu'il est encore utilisé par &lt;code&gt;Object2&lt;/code&gt;.&lt;/p&gt;


&lt;p&gt;Pour éviter cela, il faut alors passer par un pointeur &lt;em&gt;intelligent&lt;/em&gt; &lt;code&gt;this&lt;/code&gt;. Pour cela nous allons utiliser deux choses&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un membre nommé &lt;code&gt;_this&lt;/code&gt; de type pointeur &lt;em&gt;intelligent&lt;/em&gt; &lt;code&gt;QWeakPointer&lt;/code&gt;, contenant une référence à l'objet lui même. (Nous n'utilisons pas un QSharedPointer, pour éviter une référence circulaire, voir le paragraphe suivant).&lt;/li&gt;
&lt;li&gt;Une méthode statique utilisée pour la création (nous n'allons plus utiliser le constructeur, car à ce moment, il n'existe pas encore de QSharedPointer pointant vers notre objet).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voici un exemple de comment écrire le constructeur maison&amp;nbsp;:&lt;/p&gt;
&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; MyObject
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;static&lt;/span&gt; QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; create&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QString parametre&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; MyObject&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;parametre&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    ptr&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;_this &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; ptr.&lt;span style=&quot;color: #007788;&quot;&gt;toWeakRef&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  MyObject&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QString parametre&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    ...
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  QWeakPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; _this&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Le constructeur devient alors privé (ou protégé si on a besoin de la notion d'héritage) afin d'obliger l'utilisateur de la classe à utiliser notre méthode de création. Dans notre nouvelle méthode de création &lt;code&gt;create&lt;/code&gt;, qui est une méthode statique, nous allons créer le pointeur et initialiser le &lt;code&gt;QWeakPointer&lt;/code&gt; de notre objet avec le pointeur &lt;em&gt;intelligent&lt;/em&gt; que nous venons de créer. Nous retournons un &lt;code&gt;QSharedPointer&lt;/code&gt;. La méthode &lt;code&gt;create&lt;/code&gt; devient alors notre nouveau constructeur, mais créant des instances d'objets de type &lt;code&gt;QSharedPointer&amp;lt;MyObject&amp;gt;&lt;/code&gt; et non plus des instances d'objet &lt;code&gt;MyObject*&lt;/code&gt;.&lt;/p&gt;


&lt;p&gt;Notre méthode &lt;code&gt;setMember()&lt;/code&gt; peut alors être ré-écrite&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; MyObject&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;setMember&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;Object2 &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt; obj&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  _membre &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; obj&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;obj&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    obj&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;setParent&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;_this.&lt;span style=&quot;color: #007788;&quot;&gt;toStrongRef&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;&lt;a name=&quot;comment_eviter_les_references_circulaires&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Comment éviter les références circulaires&lt;/h4&gt;


&lt;p&gt;Le principe d'une référence circulaire est qu'un objet A référence l'objet B et l'objet B référence l'objet A.&lt;/p&gt;


&lt;p&gt;Voici par exemple, un cas de référence circulaire&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; A
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;static&lt;/span&gt; create&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; A&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
  ~A&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  A&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    b &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; B&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    b&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;setA&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;_this&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
  QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;B&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; b&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  QWeakPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; _this&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; B
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;static&lt;/span&gt; QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;B&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; create&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt; 
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;B&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; B&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; setA&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; b&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; getA&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;  a&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Cela peut-être aussi le cas, si par exemple une instance d'objet C référence des instances d'objets fils C, qui possèdent eux-même un pointeur vers l'objet C père.&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; C
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;static&lt;/span&gt; QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; create&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; C&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    _this &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; ptr.&lt;span style=&quot;color: #007788;&quot;&gt;toWeakPtr&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  ~C&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; addChild&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; c&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    _childs.&lt;span style=&quot;color: #007788;&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;c&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    c&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;setParent&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;_this&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; setParent&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; c&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; getParent&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  C&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  QWeakPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; _this&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; _parent&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  QList&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt; QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; _childs&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Dans ces cas là, on a&amp;nbsp;:
- L'objet A possède la référence vers l'objet B
- L'objet B possède une référence vers l'objet A.
- Même principe avec l'objet C&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qsharedpointer/QSharedPointer3.png&quot; alt=&quot;QSharedPointer3.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;QSharedPointer3.png, janv. 2011&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Dans ce cas, il restera alors toujours une référence vers A, et une vers B, même si plus aucune variable ne référence ces objets. Cette référence circulaire fait que l'objet ne sera jamais détruit même si on n'a plus besoin de l'objet.&lt;/p&gt;


&lt;p&gt;Si on décide que l'objet A sera l'objet maitre (donc que sa destruction engendrera la destruction de l'objet B), on peut alors écrire les choses ainsi pour l'objet B&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; B
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;static&lt;/span&gt; QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;B&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; create&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt; 
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;B&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; B&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; setA&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;QWeakPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; b&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  QWeakPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; getA&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
  QWeakPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;A&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;  a&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Dans ce cas, avec l'utilisation d'un &lt;code&gt;QWeakPointer&lt;/code&gt;, lorsque qu'il n'existera plus de référence vers l'objet A, le pointeur &lt;em&gt;faible&lt;/em&gt; &lt;code&gt;a&lt;/code&gt; sera mis à jour comme ne contenant plus de référence&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-3&quot; id=&quot;rev-pnote-628-3&quot;&gt;3&lt;/a&gt;]&lt;/sup&gt;. L'instance de l'objet A sera réellement détruite. Il n'y aura alors plus aucune référence vers l'objet B qui sera alors également détruit&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-4&quot; id=&quot;rev-pnote-628-4&quot;&gt;4&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;utilisation_dans_les_applications_multi_thread&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Utilisation dans les applications multi-thread.&lt;/h4&gt;


&lt;p&gt;L'utilisation de &lt;code&gt;QSharedPointer&lt;/code&gt; simplifie l'écriture des applications multi-thread (les objets &lt;code&gt;QSharedPointer&lt;/code&gt; et &lt;code&gt;QWeakPointer&lt;/code&gt; sont thread-safe).&lt;/p&gt;


&lt;p&gt;Dans ces applications il n'y a alors plus besoin de se soucier si l'objet est en cours d'utilisation ailleurs dans l'application avant de le supprimer&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-5&quot; id=&quot;rev-pnote-628-5&quot;&gt;5&lt;/a&gt;]&lt;/sup&gt;. Lorsqu'un pointeur ne devient plus utilisé dans un thread donné, il ne sera détruit que s'il n'y a pas d'autres références dans d'autres threads de l'application&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-6&quot; id=&quot;rev-pnote-628-6&quot;&gt;6&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Avec l'utilisation de &lt;code&gt;QWeakPointer&lt;/code&gt;, un thread pourra tester l'existence du pointeur avant d'effectuer une opération et pourra aviser le cas échéant sans faire planter toute l'application&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-7&quot; id=&quot;rev-pnote-628-7&quot;&gt;7&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;utilisation_d_un_pool&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Utilisation d'un pool&lt;/h4&gt;


&lt;p&gt;Si la création et la destruction d'un objet est coûteux, il est envisageable de diminuer le coût de destruction et de création d'un thread en utilisant un Pool d'objet. Dans ce cas l'objet &lt;a href=&quot;http://doc.qt.nokia.com/4.6/qqueue.html&quot; hreflang=&quot;en&quot; title=&quot;Documentation de QQueue&quot;&gt;QQueue&lt;/a&gt; pourra être utilisé pour représenter notre Pool.&lt;/p&gt;


&lt;p&gt;Lors de la demande de création, en utilisant notre méthode &lt;code&gt;create&lt;/code&gt; ci-dessus, on prend alors une valeur du pool (si disponible) et on la retourne sous forme d'un &lt;code&gt;QSharedPointer&lt;/code&gt;.&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; MyObject&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  MyObject &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt; c_ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;_queue.&lt;span style=&quot;color: #007788;&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
	c_ptr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; _queue.&lt;span style=&quot;color: #007788;&quot;&gt;dequeue&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;else&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt; 
	c_ptr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; MyObject&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
  QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;MyObject&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;c_ptr, ReturnToPool&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  ptr&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;_this &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; ptr.&lt;span style=&quot;color: #007788;&quot;&gt;toWeakRef&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Dans l'exemple ci-dessus&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-8&quot; id=&quot;rev-pnote-628-8&quot;&gt;8&lt;/a&gt;]&lt;/sup&gt;, on demande à la queue, qui doit être une variable globale ou statique, un élément, et si ce n'est pas possible, on crée un nouvel objet de type &lt;code&gt;MyObject&lt;/code&gt; (dont on suppose la création coûteuse).&lt;/p&gt;


&lt;p&gt;Lors de la création du &lt;code&gt;QSharedPointer&lt;/code&gt; on utilise alors le constructeur &lt;code&gt;QSharedPointer ( T * ptr, Deleter deleter )&lt;/code&gt; sur lequel on définit une méthode &lt;code&gt;Deleter&lt;/code&gt; nommée &lt;code&gt;ReturnToPool&lt;/code&gt; dont le but est de remettre les objets en pool.&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; ReturnToPool&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;MyObject &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt;obj&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;_queue.&lt;span style=&quot;color: #007788;&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt; MAX_SIZE_QUEUE&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
	_queue.&lt;span style=&quot;color: #007788;&quot;&gt;enqueue&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;obj&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff;&quot;&gt;else&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
	&lt;span style=&quot;color: #0000dd;&quot;&gt;delete&lt;/span&gt; obj&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
  &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Dans ce cas de retour au pool, si le pool est rempli, on détruit l'objet (pour éviter de consommer trop de mémoire), sinon on l'ajoute au pool. Dans ce cas, le pool est agrandi au fur et à mesure des besoins, jusqu'à une taille limite.&lt;/p&gt;


&lt;p&gt;Bien sûr il faut que la performance de l'utilisation d'un pool soit plus intéressante que celle de la création de l'objet et de son initialisation.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;&lt;ins&gt;Attention&lt;/ins&gt;&amp;nbsp;: Ce point ne fonctionne, par contre, pas si l'objet (&lt;code&gt;MyObject&lt;/code&gt;) est un descendant de &lt;code&gt;QObject&lt;/code&gt;. En effet &lt;code&gt;QObject&lt;/code&gt; garde une référence du &lt;code&gt;QSharedPointer&lt;/code&gt; en mémoire et lors de la réutilisation du &lt;code&gt;QObject&lt;/code&gt; une erreur indique que l'objet n'a pas été détruit et est déjà utilisé par un &lt;code&gt;QSharedPointer&lt;/code&gt;. On n'a pas le problème avec &lt;code&gt;std::tr1::shared_ptr&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;benchmark&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Benchmark&lt;/h3&gt;


&lt;p&gt;Le but du benchmark est de se faire une idée sur les performances d'une application utilisant des &lt;code&gt;QSharedPointer&lt;/code&gt; à la place des pointeurs normaux. Attention, ce bench ne prend pas en compte le besoin potentiel de Mutex, de comptage de référence manuel, ... dans les applications multi-thread qui pourrait être nécessaire pour ne pas supprimer le pointeur si besoin.&lt;/p&gt;


&lt;p&gt;Dans ce test nous allons tester également (en comparaison), le pointeur &lt;em&gt;intelligent&lt;/em&gt; du C++0x&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#pnote-628-9&quot; id=&quot;rev-pnote-628-9&quot;&gt;9&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Nous allons donc tester les opérations courantes de création, destruction, modification, affectation.&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;code_source&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Code source&lt;/h4&gt;


&lt;p&gt;Le code source est disponible, attaché au billet. Dans la suite du billet, seuls les morceaux intéressants du benchmark seront décris. Le benchmark utilise QTest. Nous avons créé un objet bidon &lt;code&gt;ObjetTest&lt;/code&gt; qui dans le constructeur allouera un pointeur et remplira une liste, et le destructeur supprime ce pointeur (et forcément la liste).&lt;/p&gt;


&lt;p&gt;Pour que chaque test soit indépendant, le jeu de test sera initialisé avant le début de chaque QBENCHMARK et détruit à la fin du bloc. Nous aurons quatre méthodes&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allocation&lt;/li&gt;
&lt;li&gt;Modification&lt;/li&gt;
&lt;li&gt;Affectation&lt;/li&gt;
&lt;li&gt;Nettoyage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pour chaque test nous allons faire le test avec&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un pointeur C standard&lt;/li&gt;
&lt;li&gt;le pointeur &lt;code&gt;QSharedPointer&lt;/code&gt; de &lt;em&gt;Qt&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;le pointeur &lt;code&gt;std::tr1::shared_ptr&lt;/code&gt; de &lt;em&gt;C++0x&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pour le test d'allocation et le test de nettoyage, nous allons également utiliser l'optimisation possible, vu ci-dessus, d'un Pool d'objet. Nous allons faire le test avec&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le pointeur &lt;code&gt;QSharedPointer&lt;/code&gt; de &lt;em&gt;Qt&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;le pointeur &lt;code&gt;std::tr1::shared_ptr&lt;/code&gt; de &lt;em&gt;C++0x&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a name=&quot;le_jeu_de_test&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Le jeu de test&lt;/h4&gt;


&lt;p&gt;&lt;a name=&quot;test_de_l_allocation&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Test de l'allocation&lt;/h5&gt;


&lt;p&gt;La création du pointeur en utilisant &lt;code&gt;QSharedPointer&lt;/code&gt; instancie le pointeur ainsi que le &lt;code&gt;QSharedPointer&lt;/code&gt;. Le temps d'exécution est donc potentiellement deux fois plus long (voir le benchmark à la fin de ce billet).&lt;/p&gt;


&lt;p&gt;Pour la création du pool, nous allons utiliser une méthode qui créera le pointeur s'il n'est pas dans le pool, et sinon prendra le pointeur du pool. Dans notre cas de test, il y aura toujours une valeur dans le pool, que l'on aura rempli au préalable.&lt;/p&gt;


&lt;p&gt;La méthode &lt;code&gt;createFromPool()&lt;/code&gt; et &lt;code&gt;createFromBoostPool()&lt;/code&gt; est sensiblement identique&amp;nbsp;:&lt;/p&gt;
&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;ObjetTest&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; createFromPool&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
        ObjetTest &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt; c_ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;_queue.&lt;span style=&quot;color: #007788;&quot;&gt;size&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
          c_ptr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; _queue.&lt;span style=&quot;color: #007788;&quot;&gt;dequeue&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
        &lt;span style=&quot;color: #0000ff;&quot;&gt;else&lt;/span&gt;
        &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
          c_ptr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; ObjetTest&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
        QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;ObjetTest&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;c_ptr, returnToPool&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
        &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; ptr&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;C Pointer&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;ObjetTest&lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt; ptr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; ObjetTest&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Qt Smart Pointer&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;ObjetTest&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; ObjetTest&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Qt Smart Pointer as Pool&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;ObjetTest&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; createFromPool &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;C++0x Smart Pointer&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;std&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;tr1&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;shared_ptr&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;ObjetTest&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;new&lt;/span&gt; ObjetTest&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;C++0x Smart Pointer as Pool&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;std&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;tr1&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;shared_ptr&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;ObjetTest&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; ptr &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; createFromBoostPool &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;&lt;a name=&quot;test_de_modification_d_une_donnee&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Test de Modification d'une donnée&lt;/h5&gt;


&lt;p&gt;Pour la modification d'une donnée, on génère un nombre aléatoire que l'on va stocker (toujours le même pour chaque test, cela n'a pas d'importance). La génération du nombre aléatoire se fait en dehors du bloc, pour éviter de polluer le test avec le calcul d'un nombre aléatoire. Ici il n'y a pas création d'affectation du pointeur, juste une affectation d'une valeur dans le contenu du pointeur. La syntaxe pour le C, et pour le pointeur intelligent est identique.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;C Pointer / Qt Smart Pointer / C++0x Smart Pointer&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;obj&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;value &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; random_number&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;&lt;a name=&quot;test_d_affectation&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Test d'affectation&lt;/h5&gt;


&lt;p&gt;Pour l'affectation nous allons créer une nouvelle variable qui pointera sur le même pointeur, et sur lequel on fera une modification. La création d'un pointeur peut arriver par exemple lors du passage du pointeur à une fonction, ou lors de la déclaration d'une variable devant contenir la même valeur. Cette déclaration supplémentaire a peu d'impact pour un pointeur C mais pour un pointeur &lt;em&gt;intelligent&lt;/em&gt; oblige la création d'un objet, et l'incrément d'un nombre d'instance (qu'on décrémente ici dans la même boucle).&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;C Pointer&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;ObjetTest &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt; obj2 &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; obj&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
obj2&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;value &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; random_number&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Qt Smart Pointer&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;QSharedPointer&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;ObjetTest&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; obj2 &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; obj&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
obj2&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;value &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; random_number&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;C++0x Smart Pointer&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;std&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;tr1&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;shared_ptr&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;ObjetTest&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt; obj2 &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; obj&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
obj2&lt;span style=&quot;color: #000040;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;value &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; random_number&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;&lt;a name=&quot;test_de_destruction&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Test de destruction&lt;/h5&gt;


&lt;p&gt;Pour ce test, nous allons initialiser une liste de pointeur, et pour le benchmark, nous allons supprimer un à un chaque élément de la liste.
La destruction du pointeur en C se fait par un &lt;code&gt;delete&lt;/code&gt;. Pour le pointeur ''intelligent', il n'y a pas de destruction explicite. Nous allons juste supprimer le pointeur de la liste, le pointeur sera alors automatiquement détruit car il n'y aura plus de référence vers ce pointeur.&lt;/p&gt;


&lt;p&gt;Pour le cas de test utilisant la notion du Pool, on aura créé le pointeur avec le delete &lt;code&gt;returnToPool()&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;
&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; returnToPool&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;ObjetTest &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt;obj&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
        _queue.&lt;span style=&quot;color: #007788;&quot;&gt;enqueue&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;obj&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Cette méthode ne fait pas de réelle destruction, mais juste un ajout de l'objet au pool.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;C Pointer&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;delete&lt;/span&gt; c_ptr_list.&lt;span style=&quot;color: #007788;&quot;&gt;at&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
c_ptr_list.&lt;span style=&quot;color: #007788;&quot;&gt;removeFirst&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Qt Smart Pointer / Qt Smart Pointer as Pool / C++0x Smart Pointer / C++0x Smart Pointer as Pool &lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;smart_ptr_list.&lt;span style=&quot;color: #007788;&quot;&gt;removeFirst&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;&lt;a name=&quot;resultat_du_test&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Résultat du test&lt;/h5&gt;


&lt;p&gt;Le test a été fait en utilisant la version 4.6.3 de Qt. Test effectué pour 5 000 000 itérations.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th/&gt;&lt;th&gt;Pointeur C&lt;/th&gt;&lt;th&gt;Pointeur Qt&lt;/th&gt;&lt;th&gt;Pointeur C++0x&lt;/th&gt;&lt;th&gt;Pool en utilisant QSharedPointer&lt;/th&gt;&lt;th&gt;Pool en utilisant std::tr1::shared_ptr&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Allocation&lt;/th&gt;&lt;td&gt;0.0004275 msec&lt;/td&gt;&lt;td&gt;0.0007692 msec&lt;/td&gt;&lt;td&gt;0.0006604 msec&lt;/td&gt;&lt;td&gt;0.0002590 msec&lt;/td&gt;&lt;td&gt;0.0002286 msec&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Modification&lt;/th&gt;&lt;td&gt;0.000010 msec&lt;/td&gt;&lt;td&gt;0.000012 msec&lt;/td&gt;&lt;td&gt;0.000012 msec&lt;/td&gt;&lt;td colspan=&quot;2&quot; rowspan=&quot;2&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Affectation&lt;/th&gt;&lt;td&gt;0.000010 msec&lt;/td&gt;&lt;td&gt;0.0000386 msec&lt;/td&gt;&lt;td&gt;0.0000230 msec&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Destruction&lt;/th&gt;&lt;td&gt;0.000190 msec&lt;/td&gt;&lt;td&gt;0.0003161 msec&lt;/td&gt;&lt;td&gt;0.0003359 msec&lt;/td&gt;&lt;td&gt;0.0004003 msec&lt;/td&gt;&lt;td&gt;0.0003601 msec&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Conclusion que l'on peut en tirer, le pointeur C est ce qu'il y a de plus rapide à partir du moment où on fait de l'allocation de l'affectation ou de la destruction. Par contre il n'apporte pas la souplesse qu'apporte les pointeurs &lt;em&gt;intelligents&lt;/em&gt; entre autre pour les applications multi-threadé.&lt;/p&gt;


&lt;p&gt;On remarque que le pointeur C++0x est plus rapide pour la création, mais apparemment plus lent en destruction. Il est également possible avec le pool de gagner en performance (surtout en création). Par contre le coût de destruction de l'objet n'est pas encore assez fort pour y gagner en utilisant le pool.&lt;/p&gt;


&lt;p&gt;Ensuite il est important de se faire son propre jugement selon ses besoins. Si besoin le source est attaché, vous pouvez faire vos propres tests.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-1&quot; id=&quot;pnote-628-1&quot;&gt;1&lt;/a&gt;] Si à un moment donné il faut utiliser le pointeur C pour une raison quelconque, on peut utiliser &lt;code&gt;ptr.data()&lt;/code&gt; mais il faut s'assurer que le pointeur ne sera pas détruit en déclarant un &lt;code&gt;QSharedPointer&lt;/code&gt; dans le même bloc utilisant le pointeur C. Le &lt;code&gt;QSharedPointer&lt;/code&gt; ne devra être détruit qu'après utilisation du pointeur C. Ceci peut être fait dans certain cas pour des raisons de performance.&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-2&quot; id=&quot;pnote-628-2&quot;&gt;2&lt;/a&gt;] Sinon nous ne serions plus là pour lancer la méthode&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-3&quot; id=&quot;pnote-628-3&quot;&gt;3&lt;/a&gt;] Le &lt;code&gt;QWeakPointeur&lt;/code&gt; ne gardant pas d'instance d'objet, car il n'incrémente pas le compteur de référence&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-4&quot; id=&quot;pnote-628-4&quot;&gt;4&lt;/a&gt;] s'il n'existe pas de référence vers l'objet B ailleurs dans l'application&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-5&quot; id=&quot;pnote-628-5&quot;&gt;5&lt;/a&gt;] Attention quand même, &lt;code&gt;QSharedPointer&lt;/code&gt; protège le pointeur mais pas le contenu&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-6&quot; id=&quot;pnote-628-6&quot;&gt;6&lt;/a&gt;] d'autres threads pouvant inclure le thread principal&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-7&quot; id=&quot;pnote-628-7&quot;&gt;7&lt;/a&gt;] Si l'objet est supprimé, &lt;code&gt;QWeakPointer&lt;/code&gt;, sera alors remis à &lt;code&gt;null&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-8&quot; id=&quot;pnote-628-8&quot;&gt;8&lt;/a&gt;] Dans le code en question, il faudrait ajouter la notion de mutex autour de la gestion de la queue, en cas de création parallèle.&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#rev-pnote-628-9&quot; id=&quot;pnote-628-9&quot;&gt;9&lt;/a&gt;] Le pointeur &lt;em&gt;intelligent&lt;/em&gt; &lt;code&gt;shared_ptr&lt;/code&gt; de C++0x à pour origine le pointeur Boost&lt;/p&gt;&lt;/div&gt;
</description>
    
          <enclosure url="http://www.shadoware.org/public/billets/qsharedpointer/smart_benchmark.7z"
      length="1805" type="text/plain" />
    
    
          <comments>http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#comment-form</comments>
      <wfw:comment>http://www.shadoware.org/post/2011/01/17/Performance-de-l-utilisation-de-QSharedPointer#comment-form</wfw:comment>
      <wfw:commentRss>http://www.shadoware.org/feed/atom/comments/628</wfw:commentRss>
      </item>
    
  <item>
    <title>[C++/Qt] Concaténation de chaînes de caractères</title>
    <link>http://www.shadoware.org/post/2010/12/21/%5BC/Qt%5D-Concat%C3%A9nation-de-chaine-de-caract%C3%A8re</link>
    <guid isPermaLink="false">urn:md5:5f35cced448e3f18b1997d657393c995</guid>
    <pubDate>Wed, 22 Dec 2010 13:03:00 +0100</pubDate>
    <dc:creator>Ulrich Van Den Hekke</dc:creator>
        <category>Performances</category>
        <category>libre</category><category>nokia</category><category>performance</category><category>planet</category><category>qstring</category><category>qt</category><category>trolltech</category>    
    <description>&lt;h3&gt;Présentation&lt;/h3&gt;


&lt;p&gt;Qt est un framework orienté objet écrit en C++ et permettant de faire des interfaces graphiques à l’aide de ces widgets. Ce framework est utilisé par le projet KDE depuis ses débuts pour en faire un environnement très complet.&lt;/p&gt;


&lt;p&gt;Qt permet donc de faire des interfaces graphiques mais aussi d’accéder à des bases de données SQL, de faire de la communication réseau, une gestion simplifiée des threads, la lecture de fichier XML. Qt intègre aussi le moteur HTML Webkit.&lt;/p&gt;


&lt;p&gt;Qt ajoute une couche supplémentaire au C++ permettant de faire de l’introspection de classe un peu plus poussée (comme l’appel d’une méthode dont on ne connaît le nom qu’à l’exécution). Qt permet également la gestion d’évènement par l’intermédiaire d’un système puissant de SIGNALS et de SLOTS.&lt;/p&gt;


&lt;p&gt;Dans la suite de cet article nous allons nous concentrer sur une très petite partie de Qt mais qui est utilisée dans beaucoup d’applications écrites en Qt&amp;nbsp;: les chaînes de caractères, et plus précisément, la concaténation de chaînes de caractères.&lt;/p&gt;    &lt;h2&gt;Concaténation de chaînes de caractères.&lt;/h2&gt;


&lt;p&gt;Comme dans d’autres langages, la concaténation de chaînes de caractères se fait à l'aide de l'opérateur &lt;code&gt;+&lt;/code&gt;. Prenons un exemple simple&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #339900;&quot;&gt;#include &amp;lt;QString&amp;gt;&lt;/span&gt;
&amp;nbsp;
QString abc &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;, def &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;def&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
QString result&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
result &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; abc &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; def&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;



&lt;p&gt;L'utilisation de l'opérateur &lt;code&gt;+&lt;/code&gt; facilite l'écriture de la concaténation des chaînes de caractères (tout comme l'opérateur &lt;code&gt;==&lt;/code&gt; permet de facilement comparer des chaînes de caractères de type QString).&lt;/p&gt;


&lt;p&gt;Malheureusement cette écriture rend le code peu performant pour diverses raisons (que l’on peut retrouver dans la documentation de l’objet QString).&lt;/p&gt;


&lt;h3&gt;Concaténation rapide de chaînes de caractères&lt;/h3&gt;


&lt;p&gt;A partir de Qt 4.6, Nokia, a ajouté un &lt;code&gt;template&lt;/code&gt; nommé QStringBuilder (cet objet fait beaucoup penser à l'objet StringBuilder de JAVA permettant d'accélérer les concaténations de chaînes de caractères).&lt;/p&gt;


&lt;p&gt;Ce template ne s’utilise pas directement mais au travers de l'opérateur &lt;code&gt;%&lt;/code&gt;. En remplaçant donc l'opérateur &lt;code&gt;+&lt;/code&gt; par &lt;code&gt;%&lt;/code&gt; on gagne en performance (dixit la doc de Qt).&lt;/p&gt;


&lt;p&gt;Pour pouvoir utiliser l'opérateur, il suffit d'inclure le fichier &lt;code&gt;QStringBuilder&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #339900;&quot;&gt;#include &amp;lt;QStringBuilder&amp;gt;&lt;/span&gt;
&amp;nbsp;
QString abc &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;, def &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;def&amp;quot;&lt;/span&gt;, ghi &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;ghi&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
QString result&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
result &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; abc &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; def &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; ghi&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Une autre possibilité est de définir (par exemple dans votre fichier .pro ou dans un include général de votre application)  les définitions &lt;code&gt;QT_USE_FAST_CONCATENATION&lt;/code&gt;,  et &lt;code&gt;QT_USE_FAST_OPERATOR_PLUS&lt;/code&gt;.&lt;/p&gt;


&lt;p&gt;Ces définitions permettent de remplacer l'opérateur &lt;code&gt;+&lt;/code&gt; par l'opérateur &lt;code&gt;%&lt;/code&gt; dans toute l'application. Par contre cette opération peut demander quelques modifications de votre code.&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #339900;&quot;&gt;#define QT_USE_FAST_CONCATENATION&lt;/span&gt;
&lt;span style=&quot;color: #339900;&quot;&gt;#define QT_USE_FAST_OPERATOR_PLUS&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #339900;&quot;&gt;#include &amp;lt;QString&amp;gt;&lt;/span&gt;
&amp;nbsp;
QString abc &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;, def &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;def&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
QString result&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
result &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; abc &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; def&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;h3&gt;Benchmark&lt;/h3&gt;


&lt;p&gt;Nous allons donc dans la suite du document vérifier que l'opérateur &lt;code&gt;%&lt;/code&gt; est plus rapide que l'opérateur &lt;code&gt;+&lt;/code&gt;. Pour cela nous allons utiliser le module de benchmark de Qt.&lt;/p&gt;


&lt;h4&gt;Code source&lt;/h4&gt;


&lt;p&gt;Voici le petit programme permettant de tester la performance de la concaténation. Notre exemple simple va constituer à la concaténation de 26 chaînes de caractères créées au début. L'appel se fera une première fois en utilisant l'opérateur &lt;code&gt;+&lt;/code&gt; et une seconde fois en utilisant l'opérateur &lt;code&gt;%&lt;/code&gt;.&lt;/p&gt;

&lt;pre class=&quot;cpp cpp&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #339900;&quot;&gt;#include &amp;lt;QtCore/QString&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #339900;&quot;&gt;#include &amp;lt;QtTest/QtTest&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #339900;&quot;&gt;#include &amp;lt;QStringBuilder&amp;gt;&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;class&lt;/span&gt; TestPerf &lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt; QObject
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
    Q_OBJECT
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
    TestPerf&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;private&lt;/span&gt; Q_SLOTS&lt;span style=&quot;color: #008080;&quot;&gt;:&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; concat&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; concat_data&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
TestPerf&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;TestPerf&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; TestPerf&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;concat&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
	QFETCH&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;bool&lt;/span&gt;, useStringBuilder&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
	QString result&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	QString a&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, b&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, c&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, d&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, e&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;e&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, f&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;f&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, g&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;g&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, h&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;h&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, i&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;i&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, j&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;j&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, k&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;k&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, l&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;l&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, m&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;m&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, n&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;n&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, o&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;o&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, p&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;p&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, q&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;q&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, r&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, s&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, t&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;t&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, u&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;u&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, v&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;v&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, w&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, x&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, y&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;y&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;, z&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;z&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;useStringBuilder&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
	&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
		QBENCHMARK
		&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
			&lt;span style=&quot;color: #666666;&quot;&gt;// Concaténation en utilisant QStringBuilder&lt;/span&gt;
			&lt;span style=&quot;color: #666666;&quot;&gt;// Dans ce cas la concaténation devrait être plus rapide&lt;/span&gt;
			result &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; a &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; b &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; c &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; d &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; e &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; f &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; g &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; h &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; i &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; j &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; k &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; l &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; m &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; n &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; o &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; p &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; q &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; r &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; s &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; t &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; u &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; v &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; w &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; x &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; y &lt;span style=&quot;color: #000040;&quot;&gt;%&lt;/span&gt; z&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
		&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
	&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
	&lt;span style=&quot;color: #0000ff;&quot;&gt;else&lt;/span&gt;
	&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
		QBENCHMARK
		&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
			&lt;span style=&quot;color: #666666;&quot;&gt;// Concaténation en n'utilisant pas QStringBuilder. On utilise alors la concaténation normal de chaînes de caractères en utilisant&lt;/span&gt;
			&lt;span style=&quot;color: #666666;&quot;&gt;// QString&lt;/span&gt;
			result &lt;span style=&quot;color: #000080;&quot;&gt;=&lt;/span&gt; a &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; b &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; c &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; d &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; e &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; f &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; g &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; h &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; i &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; j &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; k &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; l &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; m &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; n &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; o &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; p &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; q &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; r &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; s &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; t &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; u &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; v &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; w &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; x &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; y &lt;span style=&quot;color: #000040;&quot;&gt;+&lt;/span&gt; z&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
		&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
	&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt; TestPerf&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;concat_data&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;
	QTest&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;addColumn&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;bool&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;useStringBuilder&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
	QTest&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;newRow&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;Don't use QStringBuilder&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
	QTest&lt;span style=&quot;color: #008080;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #007788;&quot;&gt;newRow&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;&amp;quot;Use QStringBuilder&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
QTEST_APPLESS_MAIN&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;TestPerf&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #339900;&quot;&gt;#include &amp;quot;tst_testperf.moc&amp;quot;&lt;/span&gt;&lt;/pre&gt;


&lt;h4&gt;Résultat du test&lt;/h4&gt;


&lt;p&gt;Le test a été fait en utilisant la version 4.6.3 de Qt. Le résultat est sensiblement le même avec la version 4.7.0&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Sans QStringBuilder&lt;/th&gt;&lt;td&gt;0.00367 msec&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Avec QStringBuilder&lt;/th&gt;&lt;td&gt;0.00046 msec&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;On voit dans ce test que la version en utilisant QStringBuilder est 8 fois plus rapide que sans. Bien sûr vu le temps que prend la concaténation de chaînes de caractères, ce test commence à avoir de l'intérêt uniquement à partir du moment où on fait beaucoup de concaténation dans la seconde, ou si les temps de réponses sont critiques.&lt;/p&gt;


&lt;p&gt;Sur ce, je vous souhaite à tous un Joyeux noël et une bonne année.&lt;/p&gt;</description>
    
          <enclosure url="http://www.shadoware.org/public/billets/concat/test-perfconcat.7z"
      length="862" type="text/plain" />
    
    
          <comments>http://www.shadoware.org/post/2010/12/21/%5BC/Qt%5D-Concat%C3%A9nation-de-chaine-de-caract%C3%A8re#comment-form</comments>
      <wfw:comment>http://www.shadoware.org/post/2010/12/21/%5BC/Qt%5D-Concat%C3%A9nation-de-chaine-de-caract%C3%A8re#comment-form</wfw:comment>
      <wfw:commentRss>http://www.shadoware.org/feed/atom/comments/626</wfw:commentRss>
      </item>
    
  <item>
    <title>[Qt] Transformation d'une vue tableau en une vue hiérarchique</title>
    <link>http://www.shadoware.org/post/2009/09/10/%5BQt%5D-Transformation-d-une-vue-tableau-en-une-vue-hi%C3%A9rarchique</link>
    <guid isPermaLink="false">urn:md5:a2b92942f5d31facf73b6df365c09893</guid>
    <pubDate>Mon, 21 Sep 2009 13:50:00 +0200</pubDate>
    <dc:creator>Ulrich Van Den Hekke</dc:creator>
        <category>C++</category>
        <category>article</category><category>libre</category><category>model</category><category>nokia</category><category>planet</category><category>qt</category><category>trolltech</category>    
    <description>&lt;p&gt;Pour visualiser des données internes à l'écran, Nokia/Qt nous propose l'architecture MVC à l'aide des classes QAbstractItemModel et de ses sous classes (QAbstractListModel, QAbstractTableModel, ...). Le but de l'architecture MVC est de séparer la représentation mémoire des données, de l'affichage qu'elles auront.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/table2tree/mvc1.png&quot; alt=&quot;mvc1.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;mvc1.png, sept. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Si les données sont par exemple issue d'une requête SQL, le modèle QSqlQueryModel permet de représenter la sélection SQL, à l'écran dans un composant QTableView. Ces données sont alors représentées sous forme d'un tableau deux dimensions.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/table2tree/tableau.png&quot; alt=&quot;tableau.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;tableau.png, sept. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Si l'on veut représenter les dossiers de l'ordinateur, le modèle QDirView permet d'afficher les données de façon hiérarchique.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/table2tree/qdirview.png&quot; alt=&quot;qdirview.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;qdirview.png, sept. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Il est également possible d'écrire nos propres modèles pour représenter nos propres données.&lt;/p&gt;


&lt;p&gt;Le but de cet article est de présenter l'écriture d'un modèle, transformant une vue plane (tableau deux dimensions) en vue hiérarchique. Pour cela nous allons prendre l'exemple de l'affichage d'une liste de catégorie&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/09/10/%5BQt%5D-Transformation-d-une-vue-tableau-en-une-vue-hi%C3%A9rarchique#pnote-623-1&quot; id=&quot;rev-pnote-623-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/09/10/%5BQt%5D-Transformation-d-une-vue-tableau-en-une-vue-hi%C3%A9rarchique#rev-pnote-623-1&quot; id=&quot;pnote-623-1&quot;&gt;1&lt;/a&gt;] La construction de notre objet s'est basé sur l'analyse de l'objet QSortFilterProxyModel de Nokia.&lt;/p&gt;&lt;/div&gt;
    &lt;h3&gt;Présentation de l'exemple&lt;/h3&gt;


&lt;p&gt;Nous allons voir ci-dessous comment transformer une vue plane en une vue hiérarchique. Pour cela nous allons prendre l'exemple d'une liste de catégorie. Ces catégories seront stockées dans une base de données Sqlite. Ceci n'a pas d'importance mais permet d'expliquer pourquoi les données en mémoire ne sont pas déjà sous forme hiérarchique.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/table2tree/proxymodel.png&quot; alt=&quot;proxymodel.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;proxymodel.png, sept. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;La description d'une catégorie passe donc par&amp;nbsp;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;un identifiant unique appelé &lt;em&gt;id&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;un nom de catégorie&lt;/li&gt;
&lt;li&gt;un lien vers la catégorie parente appelé &lt;em&gt;parent_id&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;C'est le champ &lt;em&gt;parent_id&lt;/em&gt; qui permettra de déterminer dans quelle catégorie notre sous-catégorie se trouve. Dans notre cas, &lt;em&gt;test3&lt;/em&gt; a comme &lt;em&gt;parent_id&lt;/em&gt; l'identifiant 11 qui est la catégorie &lt;em&gt;test&lt;/em&gt;.&lt;/p&gt;


&lt;p&gt;Dans notre exemple, nous allons nous conditionner à un modèle en lecture seul. Il est également possible de faire un modèle en lecture/écriture mais nous n'en parlerons pas dans cet article. Nous nous cantonnerons donc à un modèle lecture seul sur un modèle source de type &lt;em&gt;QSqlTableView&lt;/em&gt;. (Un modèle en lecture/écriture peut nécessiter de mettre à jour notre structure, ce qui peut être assez compliqué, par exemple en cas de changement de la catégorie parente).&lt;/p&gt;


&lt;h3&gt;Déclaration d'un modèle&lt;/h3&gt;


&lt;h4&gt;Qu'est qu'un proxy&amp;nbsp;?&lt;/h4&gt;


&lt;p&gt;Notre interface se basera sur la classe &lt;em&gt;QAbstractProxyModel&lt;/em&gt;. Le but de cette classe est de permettre de faire une transposition entre un premier modèle et une vue. Elle peut par exemple (à l'aide de &lt;em&gt;QSortFilterProxyModel&lt;/em&gt;) permettre de filtrer ou trier les données d'une vue.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/table2tree/mvc.png&quot; alt=&quot;mvc.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;mvc.png, sept. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Cette vue nous permettra de faire la transposition entre un modèle tableau et une vue arborescente.&lt;/p&gt;


&lt;h4&gt;Interface du proxy&lt;/h4&gt;


&lt;p&gt;Les méthodes à ré-implémenter pour faire fonctionner une proxy, sont les suivantes&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;virtual QModelIndex index&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; row&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; column&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; QModelIndex &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt; parent &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
virtual QModelIndex parent&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; QModelIndex &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt; index &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
virtual &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; rowCount&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; QModelIndex &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt; parent &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
virtual &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; columnCount&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; QModelIndex &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt; parent &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
virtual QModelIndex mapFromSource &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; QModelIndex &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt; sourceIndex &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
virtual QModelIndex mapToSource &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; QModelIndex &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt; proxyIndex &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Les quatre premières méthodes appartiennent à l'objet &lt;em&gt;QAbstractItemModel&lt;/em&gt; et seront questionnées par la vue (liste, arbre, …) pour connaître la représentation à l'écran.&lt;/p&gt;


&lt;p&gt;Les méthodes &lt;em&gt;mapFromSource()&lt;/em&gt;, et &lt;em&gt;mapToSource()&lt;/em&gt; sont à implémenter pour l'objet &lt;em&gt;QAbstractProxyModel&lt;/em&gt;. Elles permettent de faire la liaison entre les indexes (&lt;em&gt;QModelIndex&lt;/em&gt;) du modèle d'origine et les indexes du nouveau modèle.&lt;/p&gt;


&lt;p&gt;Les méthodes &lt;em&gt;data()&lt;/em&gt;, &lt;em&gt;headerData()&lt;/em&gt;, &lt;em&gt;flags()&lt;/em&gt; sont réimplémentées par l'objet &lt;em&gt;QAbstractProxyModel&lt;/em&gt; et utilisent les méthodes &lt;em&gt;mapFromSource()&lt;/em&gt; et &lt;em&gt;mapToSource()&lt;/em&gt; pour, lors de l'appel d'une de ces méthodes, récupérer les informations stockées sur le modèle d'origine.&lt;/p&gt;


&lt;p&gt;Des méthodes &lt;em&gt;sourceModel()&lt;/em&gt; et &lt;em&gt;setSourceModel()&lt;/em&gt; permettent de spécifier le modèle d'origine.&lt;/p&gt;


&lt;h3&gt;Implémentation de notre modèle&lt;/h3&gt;


&lt;h4&gt;Structure interne&lt;/h4&gt;


&lt;p&gt;Nous allons, dans cette partie, parler de la structure interne utilisée par notre objet.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #993333;&quot;&gt;struct&lt;/span&gt; Mapping &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
	&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; id&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; parrentId&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; index&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; parentIndex&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	QVector&lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt;int&lt;span style=&quot;color: #339933;&quot;&gt;&amp;gt;&lt;/span&gt; source_rows&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #993333;&quot;&gt;typedef&lt;/span&gt; QMap&lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt;int&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt;Mapping&lt;span style=&quot;color: #339933;&quot;&gt;*&amp;gt;&lt;/span&gt; IndexMap&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
IndexMap m_sourcesIndexMapping&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
QHash&lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt;int&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt;int&lt;span style=&quot;color: #339933;&quot;&gt;&amp;gt;&lt;/span&gt; m_categoryIdMapping&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous allons créer une structure &lt;em&gt;Mapping&lt;/em&gt; qui associera pour une ligne dans le modèle source, les informations concernant&amp;nbsp;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;l'identifiant de la ligne.&lt;/li&gt;
&lt;li&gt;l'identifiant de la ligne parente.&lt;/li&gt;
&lt;li&gt;l'index dans  le modèle source.&lt;/li&gt;
&lt;li&gt;l'index du parent dans le modèle source.&lt;/li&gt;
&lt;li&gt;la liste des indexes dans le modèle source des enfants dans notre modèle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Une table de hashage permettra de retrouver à partir d'un identifiant (id), la ligne dans le modèle source correspondante. On ne gardera que la seconde colonne (le nom de la catégorie), on ne fera donc l'association qu'entre le nom de la colonne de notre modèle et le modèle source en dure dans le programme.&lt;/p&gt;


&lt;h4&gt;createMapping()&lt;/h4&gt;


&lt;p&gt;Le but de cette méthode est de générer l'arborescence qui sera ensuite utilisée dans la suite des méthodes. Cette arborescence étant générée une fois pour toute (ou à chaque fois que le modèle source sera réinitialisé), il faudra parcourir l'ensemble des lignes du modèle source pour construire notre arbre. Parcourir l'ensemble des lignes du modèle source peut prendre du temps si ce dernier contient beaucoup de ligne.&lt;/p&gt;


&lt;p&gt;Nous allons considérer dans la suite, que l'identifiant de ligne 1 (id) correspond à la catégorie de plus haut niveau (ci-dessus du nom de &lt;em&gt;Categories&lt;/em&gt;). Nous allons créer une catégorie fictive 0 qui correspondra à la racine de notre modèle. Cette catégorie sera donc la catégorie parente de celle à l'identifiant 1.
Dans notre modèle source, la catégorie 0 n'a pas d'équivalence parmi les lignes du modèle source. Nous allons donc lui associer la ligne -1 dans le modèle source.&lt;/p&gt;


&lt;p&gt;Maintenant voyons la génération de la structure interne.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;qDeleteAll&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; m_sourcesIndexMapping &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
m_categoryIdMapping.&lt;span style=&quot;color: #202020;&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous commençons ci-dessous par nettoyer les différentes structures afin de les régénérer. Il faudra à la suite de la création du mapping appeler la méthode &lt;em&gt;reset()&lt;/em&gt; afin de prévenir la vue que l'ensemble des indexes du modèle sont obsolètes.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; source_rows &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourceModel&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;rowCount&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; i &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; i &lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt; source_rows&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;++&lt;/span&gt;i &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
	Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; m &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; new Mapping&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	IndexMap&lt;span style=&quot;color: #339933;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #202020;&quot;&gt;const_iterator&lt;/span&gt; it &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; IndexMap&lt;span style=&quot;color: #339933;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #202020;&quot;&gt;const_iterator&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;insert&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; i&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; m &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	m&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;index &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; i&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	m&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;parrentId &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	m&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;parentIndex &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; i &lt;span style=&quot;color: #339933;&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
		QSqlRecord record &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourceModel&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;record&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; i &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
		m_categoryIdMapping&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt; record.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; list_id &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #202020;&quot;&gt;toInt&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; i&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
		m&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;id &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; record.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; list_id &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #202020;&quot;&gt;toInt&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span style=&quot;color: #666666; font-style: italic;&quot;&gt;// Create the root Item&lt;/span&gt;
		m&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;id &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
		m_categoryIdMapping&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous récupérons le nombre de ligne dans le modèle source et commençons à initialiser notre structure. Le but de cette boucle est surtout d'initialiser dans notre correspondance identifiant/index (&lt;em&gt;m_categoryIdMapping&lt;/em&gt;), l'emplacement des identifiants dans notre tableau. Ainsi dans la suite lorsque l'on essaiera d'associer une ligne à son parent, nous pourrons savoir à quel emplacement retrouver notre id dans la structure &lt;em&gt;m_sourcesIndexMapping&lt;/em&gt;.&lt;/p&gt;


&lt;p&gt;Nous profitons également de cette boucle pour initialiser les différents champs de notre structure comme l'index (qui correspond à la ligne dans le modèle source), et l'id qui correspond à un identifiant unique dans notre liste.&lt;/p&gt;


&lt;p&gt;Nous n'oublions pas notre cas particulier que représente notre racine (ligne source -1 inexistante).&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; i &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; i &lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt; source_rows&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;++&lt;/span&gt;i &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
	QSqlRecord record &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourceModel&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;record&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; i &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; parentCategoryId &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; record.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; list_parentid &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: #202020;&quot;&gt;toInt&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; parentCategoryIndex &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_categoryIdMapping.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; parentCategoryId&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	Q_ASSERT&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; parentCategoryIndex &lt;span style=&quot;color: #339933;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; mapping &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; i &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	mapping&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;parentIndex &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; parentCategoryIndex&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	mapping&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;parrentId   &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; parentCategoryId&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; categoryMapping &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; parentCategoryIndex &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	categoryMapping&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;source_rows.&lt;span style=&quot;color: #202020;&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; i &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Enfin pour chaque enregistrement de notre modèle source, nous récupérons l'identifiant du parent et   recherchons dans la structure que nous venons de créer l'index dans le modèle source de la  catégorie parente.&lt;/p&gt;


&lt;p&gt;Ces valeurs sont alors renseignées dans le modèle. Nos ajoutons également dans la structure de &lt;em&gt;mapping&lt;/em&gt; de la catégorie parent, notre ligne dans la liste des enfants.&lt;/p&gt;


&lt;p&gt;Notre structure est ainsi complètement initialisé. Un identifiant connaît donc son parent, et la liste de ses enfants. C'est sur cette structure que se basera le reste des méthodes de notre modèle.&lt;/p&gt;


&lt;h4&gt;mapFromSource()&lt;/h4&gt;


&lt;p&gt;Le but de cette méthode est de convertir notre index venant du modèle source vers un index de notre modèle à nous.&lt;/p&gt;


&lt;p&gt;L'index du modèle source nous donne l'emplacement de la donnée dans le modèle source sous forme (ligne, colonne) alors que l'index de notre modèle doit donner l'emplacement dans notre modèle sous la forme (ligne, colonne, pointeur indiquant le parent).&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!&lt;/span&gt; sourceIndex.&lt;span style=&quot;color: #202020;&quot;&gt;isValid&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceIndex.&lt;span style=&quot;color: #202020;&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; m_sourceModel &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
	qWarning&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;CategoryItemModel: index from wrong model passed to mapFromSource&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Il faut donc d'abord vérifier que l'index du modèle source est valide. S'il n'est pas valide, alors il ne sera pas valide non plus dans notre modèle à nous.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; row &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; sourceIndex.&lt;span style=&quot;color: #202020;&quot;&gt;row&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
IndexMap&lt;span style=&quot;color: #339933;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #202020;&quot;&gt;const_iterator&lt;/span&gt; it &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;constFind&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; row &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
Q_ASSERT&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; it &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;constEnd&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous récupérons l'index dans le modèle source, et à l'aide de notre tableau d'index source, nous allons retrouver l'objet &lt;em&gt;Mapping&lt;/em&gt; correspondant. Cette objet &lt;em&gt;Mapping&lt;/em&gt; correspondra à celui de notre index source. Ce dont nous avons besoin pour notre modèle est l'objet &lt;em&gt;Mapping&lt;/em&gt; de l'objet parent (En effet, notre index est construit sous la forme&amp;nbsp;: ligne, colonne, pointeur sur la structure &lt;em&gt;Mapping&lt;/em&gt; du parent de notre index). Nous récupérons donc l'index de la ligne source dans l'objet parent.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; parentRow &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; it.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;parentIndex&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
IndexMap&lt;span style=&quot;color: #339933;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #202020;&quot;&gt;const_iterator&lt;/span&gt; parentIt &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;constFind&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; parentRow &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
Q_ASSERT&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; parentIt &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;constEnd&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; m &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; parentIt.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Cela nous permet de récupérer l'objet &lt;em&gt;Mapping&lt;/em&gt; de l'index parent.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; proxyRow    &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;source_rows.&lt;span style=&quot;color: #202020;&quot;&gt;indexOf&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; row &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; proxyColumn &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; sourceColumnToProxy&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceIndex.&lt;span style=&quot;color: #202020;&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; proxyColumn &lt;span style=&quot;color: #339933;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;La méthode &lt;em&gt;sourceColumnToProxy()&lt;/em&gt; permet de transformer une colonne de l'objet source en une colonne de l'objet courant. Cela signifie que la colonne 2 sera convertie en colonne 1, et que les colonnes 1 et 3 ne seront pas converties (et cachées). Dans ce dernier cas, nous retournons &lt;em&gt;QModelIndex()&lt;/em&gt;.&lt;/p&gt;


&lt;p&gt;L'index de la ligne dans notre modèle sera donné par la position dans la liste &lt;em&gt;source_rows&lt;/em&gt; dans notre structure de conversion.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; createIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; proxyRow&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; proxyColumn&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;parentIt &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous pouvons alors créer notre index.&lt;/p&gt;


&lt;h4&gt;mapToSource()&lt;/h4&gt;


&lt;p&gt;De la manière inverse à la méthode &lt;em&gt;mapFromSource()&lt;/em&gt;, cette méthode permet de convertir un index de notre objet en un index du modèle source.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!&lt;/span&gt; proxyIndex.&lt;span style=&quot;color: #202020;&quot;&gt;isValid&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; proxyIndex.&lt;span style=&quot;color: #202020;&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; this &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
	qWarning&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;CategoryItemModel: index from wrong model passed to mapToSource&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Si le modèle est invalide  dans notre modèle, il l'est aussi dans le modèle source. Il n'y a pas d'équivalent dans le modèle source de l'index racine.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; m &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; static_cast&lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt;Mapping&lt;span style=&quot;color: #339933;&quot;&gt;*&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; proxyIndex.&lt;span style=&quot;color: #202020;&quot;&gt;internalPointer&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous récupérons la structure dans le pointeur interne de notre index.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; sourceColumn &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; proxyColumnToSource&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; proxyIndex.&lt;span style=&quot;color: #202020;&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceColumn &lt;span style=&quot;color: #339933;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous récupérons également les informations sur notre colonne (Soit, conversion de la colonne 0 dans notre modèle, en la colonne 1 dans le modèle source).&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; sourceRow &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;source_rows.&lt;span style=&quot;color: #202020;&quot;&gt;at&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; proxyIndex.&lt;span style=&quot;color: #202020;&quot;&gt;row&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous recherchons dans notre liste &lt;em&gt;source_rows&lt;/em&gt; la ligne dans le modèle source qui correspond à la ligne (relative au père) indiqué par notre index et nous construisons un index de type (ligne, colonne) correspondant au modèle source.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; m_sourceModel&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;index&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceRow&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; sourceColumn &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;L'implémentation des méthodes &lt;em&gt;mapFromSource()&lt;/em&gt; et &lt;em&gt;mapToSource()&lt;/em&gt; permettent de faire fonctionner les implémentations des méthodes &lt;em&gt;data()&lt;/em&gt;, &lt;em&gt;headerData()&lt;/em&gt;, et &lt;em&gt;flags()&lt;/em&gt;. Il n'y aura donc aucun intérêt à ré-implémenter ces méthodes à moins de vouloir traiter les données de ces fonctions. Nous ne les décrirons donc pas ici, mais vous pourrez voir dans le fichier attaché, un exemple d'utilisation.&lt;/p&gt;


&lt;h4&gt;index()&lt;/h4&gt;

&lt;p&gt;Le principe de cette méthode est de générer un index pour notre modèle. L'index doit être valide et réutilisable dans les méthodes &lt;em&gt;rowCount()&lt;/em&gt;, &lt;em&gt;flags()&lt;/em&gt;, &lt;em&gt;columnCount()&lt;/em&gt;, &lt;em&gt;data()&lt;/em&gt;, &lt;em&gt;mapToSource()&lt;/em&gt;.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; row &lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; column &lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Si la ligne ou la colonne est inférieure à 0, l'index n'est pas valide.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;IndexMap&lt;span style=&quot;color: #339933;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #202020;&quot;&gt;const_iterator&lt;/span&gt; it &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;constFind&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
QModelIndex sourceParent &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; mapToSource&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; parent &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceParent.&lt;span style=&quot;color: #202020;&quot;&gt;isValid&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
	it &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;constFind&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceParent.&lt;span style=&quot;color: #202020;&quot;&gt;row&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;A partir de l'index &lt;em&gt;parent&lt;/em&gt; nous retrouvons l'index qui correspond dans le modèle source (&lt;em&gt;sourceParent').  Si l'on ne trouve pas d'index dans le modèle source, nous considérons être sur l'élément racine de notre arbre. Sinon nous recherchons dans la table de &lt;/em&gt;Mapping'' la structure qui correspond.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;Q_ASSERT&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; it &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;constEnd&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; it.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;source_rows.&lt;span style=&quot;color: #202020;&quot;&gt;count&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;=&lt;/span&gt; row &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;
	&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Nous vérifions le nombre d'élément dans la structure et nous retournons un index non valide si l'index demandé va au delà de la taille du tableau.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; createIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; row&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; column&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;it &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Finalement nous retournons l'index créé avec le pointeur vers la structure &lt;em&gt;Mapping&lt;/em&gt; du père en &lt;em&gt;internalData&lt;/em&gt;.&lt;/p&gt;


&lt;h4&gt;parent()&lt;/h4&gt;


&lt;p&gt;Cette méthode permet de retourner pour l'index donné du proxy, l'index du parent. Un index invalide n'a pas de parent.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!&lt;/span&gt; index.&lt;span style=&quot;color: #202020;&quot;&gt;isValid&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; m &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; static_cast&lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt;Mapping&lt;span style=&quot;color: #339933;&quot;&gt;*&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; index.&lt;span style=&quot;color: #202020;&quot;&gt;internalPointer&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;On récupère la structure de correspondance stockée dans le pointeur interne de l'objet. Cette  structure nous donne les informations du parent (en effet dans &lt;em&gt;internalPointer()&lt;/em&gt;, on stock la structure &lt;em&gt;Mapping&lt;/em&gt; du parent), et donc l'index dans le modèle source.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; sourceRow &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;index&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceRow &lt;span style=&quot;color: #339933;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; QModelIndex&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
QModelIndex sourceParent &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourceModel&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;index&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceRow&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; proxyColumnToSource&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
QModelIndex proxyParent &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; mapFromSource&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceParent &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;On utilise alors notre méthode &lt;em&gt;mapFromSource()&lt;/em&gt; pour retrouver l'index du parent dans le référentiel du proxy.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; proxyParent&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;h4&gt;rowCount()&lt;/h4&gt;


&lt;p&gt;Le but de cette méthode est de retourner le nombre de ligne enfant pour un index. Dans le modèle source les indexes n'ont pas d'enfant.
Lorsque l'index vaut &lt;em&gt;QModelIndex()&lt;/em&gt;, cela signifie qu'il faut retourner le nombre de ligne pour notre racine.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; index.&lt;span style=&quot;color: #202020;&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Seul la première colonne a des enfants.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!&lt;/span&gt; index.&lt;span style=&quot;color: #202020;&quot;&gt;isValid&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
	Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; rootMapping &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; rootMapping&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;source_rows.&lt;span style=&quot;color: #202020;&quot;&gt;count&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Pour l'index racine, on récupère le nombre de ligne à la ligne -1 du modèle source.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
	Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; parrentMapping &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; static_cast&lt;span style=&quot;color: #339933;&quot;&gt;&amp;lt;&lt;/span&gt;Mapping&lt;span style=&quot;color: #339933;&quot;&gt;*&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; index.&lt;span style=&quot;color: #202020;&quot;&gt;internalPointer&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; sourceRowIndex &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; parrentMapping&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;source_rows.&lt;span style=&quot;color: #202020;&quot;&gt;at&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; index.&lt;span style=&quot;color: #202020;&quot;&gt;row&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
	Mapping &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; rowMapping &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; m_sourcesIndexMapping.&lt;span style=&quot;color: #202020;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceRowIndex &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; rowMapping&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;source_rows.&lt;span style=&quot;color: #202020;&quot;&gt;count&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Sinon on récupère la structure stockée dans le pointeur interne. Cette structure est celle du parent de notre objet. On récupère à l'aide de la méthode &lt;em&gt;row()&lt;/em&gt; de l'index l'emplacement de la ligne source. Cette ligne source nous permet de récupérer la structure de correspondance de notre index, et ainsi le nombre de ligne de notre index.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;h4&gt;columnCount()&lt;/h4&gt;


&lt;p&gt;Notre modèle ne possède qu'une seule colonne.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;h4&gt;proxyColumnToSource()&lt;/h4&gt;


&lt;p&gt;Si la colonne du proxy vaut 0, alors on retourne la colonne 1, sinon on retourne la colonne -1&amp;nbsp;: la colonne n'est pas convertible, elle n'existe pas dans notre proxy.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; proxyColumn &lt;span style=&quot;color: #339933;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;
	&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; list_name&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;


&lt;h4&gt;sourceColumToProxy()&lt;/h4&gt;


&lt;p&gt;Si la colonne source est 1, alors nous convertissons celle-ci en la colonne 0. Sinon la colonne n'existe pas dans notre proxy.&lt;/p&gt;

&lt;pre class=&quot;c c&quot; style=&quot;font-family:inherit&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt; sourceColumn &lt;span style=&quot;color: #339933;&quot;&gt;==&lt;/span&gt; list_name &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;
	&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;</description>
    
          <enclosure url="http://www.shadoware.org/public/billets/qt/table2tree/categoryitemmodel.cpp"
      length="8272" type="text/plain" />
          <enclosure url="http://www.shadoware.org/public/billets/qt/table2tree/categoryitemmodel.h"
      length="3018" type="text/plain" />
    
    
          <comments>http://www.shadoware.org/post/2009/09/10/%5BQt%5D-Transformation-d-une-vue-tableau-en-une-vue-hi%C3%A9rarchique#comment-form</comments>
      <wfw:comment>http://www.shadoware.org/post/2009/09/10/%5BQt%5D-Transformation-d-une-vue-tableau-en-une-vue-hi%C3%A9rarchique#comment-form</wfw:comment>
      <wfw:commentRss>http://www.shadoware.org/feed/atom/comments/623</wfw:commentRss>
      </item>
    
  <item>
    <title>Qt 4.5 est sortie</title>
    <link>http://www.shadoware.org/post/2009/03/03/Qt-4.5-est-sortie</link>
    <guid isPermaLink="false">urn:md5:64ae6f28b3981e32fa5d8e9568c8220c</guid>
    <pubDate>Tue, 03 Mar 2009 16:42:00 +0100</pubDate>
    <dc:creator>Ulrich Van Den Hekke</dc:creator>
        <category>Logiciels</category>
        <category>kde</category><category>nokia</category><category>planet</category><category>qmake</category><category>qt</category>    
    <description>    &lt;p&gt;Voilà quelques heures que la dernière version de &lt;em&gt;Qt&lt;/em&gt; est sortie. Cette version, numéroté 4.5, est essentiellement orienté performance.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/logo_nokia_qt.png&quot; alt=&quot;Logo Nokia/Qt&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Logo Nokia/Qt, fév. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Elle contient entre autre &lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/03/03/Qt-4.5-est-sortie#pnote-617-1&quot; id=&quot;rev-pnote-617-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une mise à jour de &lt;em&gt;QtWebKit&lt;/em&gt; vers un version de &lt;em&gt;WebKit&lt;/em&gt; plus récente (avec un nouveau moteur JavaScript plus rapide, la possibilité d'ajouter des greffons comme &lt;em&gt;Flash&lt;/em&gt;...). Il est également possible d'utiliser les balises d'HTML 5.&lt;/li&gt;
&lt;li&gt;Amélioration des performances sur le moteur de rendu ainsi que sur le rendu du texte. Une librairie permettant de faire des tests de performance a été incluse&amp;nbsp;: &lt;em&gt;QtBenchLib&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Le support de &lt;em&gt;Mac OS X Cocoa&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;La possibilité de faire des transformations XSLT&lt;/li&gt;
&lt;li&gt;Un débuggeur &lt;em&gt;QtScript&lt;/em&gt;&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/03/03/Qt-4.5-est-sortie#pnote-617-2&quot; id=&quot;rev-pnote-617-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/qtscript-debugger-small.png&quot; alt=&quot;Qt Script Debuger&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Qt Script Debugger, mar. 2009&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Le support du format &lt;em&gt;OpenDocument&lt;/em&gt; (ODF version 1.0, ne supportant que le texte et les images)&lt;/li&gt;
&lt;li&gt;Amélioration du support des proxys&lt;/li&gt;
&lt;li&gt;Amélioration de &lt;em&gt;QtDesigner&lt;/em&gt;, &lt;em&gt;QtLinguist&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Une meilleur intégration au thème Gtk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cette nouvelle version apporte également une grande nouveauté puisqu'elle est &lt;em&gt;LGPL&lt;/em&gt;. Il est donc désormais possible de faire une application propriétaire à l'aide de cette librairie sans prendre une licence chez &lt;em&gt;Qt Software&lt;/em&gt;. Par contre si une entreprise souhaite un support pour la librairie, il faudra tout de même acheter une licence.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/.ScreenShot166_s.jpg&quot; alt=&quot;Téléchargement de Qt 4.5&quot; style=&quot;float:right; margin: 0 0 1em 1em;&quot; title=&quot;Téléchargement de Qt 4.5, mar. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;La sortie de &lt;em&gt;Qt&lt;/em&gt; 4.5 est accompagné de &lt;em&gt;Qt Creator&lt;/em&gt; 1.0. &lt;em&gt;Qt Creator&lt;/em&gt; est l'outil dernier né de chez &lt;em&gt;Qt Software&lt;/em&gt; (branche de &lt;em&gt;Nokia&lt;/em&gt;) et est un IDE de développement de programme &lt;em&gt;Qt&lt;/em&gt;. Un paquet est proposé contenant &lt;em&gt;Qt&lt;/em&gt;, &lt;em&gt;Qt Creator&lt;/em&gt;, ainsi que &lt;em&gt;MinGW&lt;/em&gt; et permettant d'avoir une installation tout en un d'un poste de développement.&lt;/p&gt;


&lt;p&gt;Vous pouvez donc aller télécharger la dernière version de &lt;em&gt;Qt&lt;/em&gt;, ainsi que de &lt;em&gt;Qt Creator&lt;/em&gt; (attention les serveurs sont surchargés) à cette &lt;a href=&quot;http://www.qtsoftware.com/downloads&quot; hreflang=&quot;fr&quot;&gt;adresse&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;Je remercie toute l'équipe de nouvellement &lt;em&gt;Qt Software&lt;/em&gt; de cette nouvelle version.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/03/03/Qt-4.5-est-sortie#rev-pnote-617-1&quot; id=&quot;pnote-617-1&quot;&gt;1&lt;/a&gt;] pour plus de détail voir &lt;a href=&quot;http://doc.trolltech.com/4.5/qt4-5-intro.html&quot; hreflang=&quot;fr&quot;&gt;http://doc.trolltech.com/4.5/qt4-5-intro.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/03/03/Qt-4.5-est-sortie#rev-pnote-617-2&quot; id=&quot;pnote-617-2&quot;&gt;2&lt;/a&gt;] L'image du debugger viens du site &lt;em&gt;Qt Software&lt;/em&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
          <enclosure url="http://www.shadoware.org/public/billets/qt/changes-4.5"
      length="59463" type="text/plain" />
    
    
          <comments>http://www.shadoware.org/post/2009/03/03/Qt-4.5-est-sortie#comment-form</comments>
      <wfw:comment>http://www.shadoware.org/post/2009/03/03/Qt-4.5-est-sortie#comment-form</wfw:comment>
      <wfw:commentRss>http://www.shadoware.org/feed/atom/comments/617</wfw:commentRss>
      </item>
    
  <item>
    <title>XINX - Editeur de feuille de style</title>
    <link>http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier</link>
    <guid isPermaLink="false">urn:md5:970880929e6507cf3b788a388c53e206</guid>
    <pubDate>Wed, 18 Feb 2009 19:00:00 +0100</pubDate>
    <dc:creator>Ulrich Van Den Hekke</dc:creator>
        <category>XINX</category>
        <category>egx</category><category>generix</category><category>generix group</category><category>nokia</category><category>qt</category><category>trolltech</category><category>xinx</category>    
    <description>&lt;p&gt;Bonjours à tous,&lt;/p&gt;


&lt;p&gt;Ce billet, parle de &lt;strong&gt;XINX&lt;/strong&gt;, un logiciel libre que j'ai développé et que je continue à développer sur mon temps libre. Le but de se billet est de présenter &lt;strong&gt;XINX&lt;/strong&gt; et d'être le début d'une longue série de billet parlant de son développement.&lt;/p&gt;


&lt;p&gt;En effet, même si le programme est propre à une utilisation particulière pour un cercle de personne restreint, les méthodes, classes, et idées utilisées dans ce programme peuvent intéresser d'autres personnes.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/xinx/.ScreenShot151_m.jpg&quot; alt=&quot;Nouvelle version de XINX&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Nouvelle version de XINX, fév. 2009&quot; /&gt;&lt;/p&gt;    &lt;h3&gt;Présentation&lt;/h3&gt;


&lt;p&gt;&lt;strong&gt;XINX&lt;/strong&gt; est un éditeur de feuille de style sur lequel je travail depuis début 2006. En faite j'avais commencé un autre éditeur à l'aide de &lt;strong&gt;Borland/Delphi 7&lt;/strong&gt; mais il a été rapidement arrêté pour prendre une nouvelle direction dans un nouveau langage avec un nouveau départ&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#pnote-613-1&quot; id=&quot;rev-pnote-613-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Cet éditeur de feuille de style à la particularité de pouvoir être utilisé dans le cadre de mon travail&amp;nbsp;: sur l'application &lt;em&gt;eGx&lt;/em&gt; (de la société &lt;strong&gt;&lt;a href=&quot;http://www.fr.generixgroup.com&quot; hreflang=&quot;fr&quot;&gt;Générix&lt;/a&gt;&lt;/strong&gt;&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#pnote-613-2&quot; id=&quot;rev-pnote-613-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;). &lt;strong&gt;XINX&lt;/strong&gt; permet non seulement l'édition de feuille de style (XSL), en proposant une &lt;em&gt;complétion&lt;/em&gt; intuitive, mais propose également un mode projet,  dans lequel il est possible de dérivé une feuille de style plutôt que de la remplacer (de façon spécifique à notre méthode de travail en projet chez le client).&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;XINX&lt;/strong&gt; est un acronyme récursive&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#pnote-613-3&quot; id=&quot;rev-pnote-613-3&quot;&gt;3&lt;/a&gt;]&lt;/sup&gt; qui signifie &lt;em&gt;XINX Is Not XDME&lt;/em&gt;. Ce nom a été choisis car &lt;strong&gt;XINX&lt;/strong&gt; est le complément idéal à &lt;strong&gt;XDME&lt;/strong&gt; (l'éditeur de fichier de configuration d&lt;em&gt;'eGx&lt;/em&gt;).&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/logo_nokia_qt.png&quot; alt=&quot;Logo Nokia/Qt&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Logo Nokia/Qt, fév. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Au niveau du choix du langage, a contrario des autres applications &lt;strong&gt;Generix&lt;/strong&gt; écritent en &lt;em&gt;JAVA&lt;/em&gt;, &lt;strong&gt;XINX&lt;/strong&gt; a été programmé en &lt;em&gt;C++&lt;/em&gt;. Le framework &lt;em&gt;Qt&lt;/em&gt; de la société &lt;del&gt;Trolltech&lt;/del&gt;&lt;strong&gt;Nokia&lt;/strong&gt; a été choisis pour simplifier la programmation. Pourquoi ce choix de langage&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;XINX&lt;/strong&gt; est une application écrite sur mon temps libre, j'ai donc choisis un langage que je souhaité apprendre. En faite la raison de l'existence de &lt;strong&gt;XINX&lt;/strong&gt;, et la volonté d'apprendre à utiliser ce framework.&lt;/li&gt;
&lt;li&gt;Le framework &lt;em&gt;Qt&lt;/em&gt; est utilisé par l'environnement de bureau &lt;strong&gt;KDE&lt;/strong&gt;. Cet environnement de bureau est celui que j'utilise tous les jours, pendant mon temps libre (chez moi), sous &lt;strong&gt;Gnu/Linux&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;La version 4 de ce framework est utilisable sous &lt;strong&gt;MS/Windows&lt;/strong&gt;, sans payer de licence, dans le cadre de l'écriture d'un logiciel libre (au bureau tout nos poste sont sous &lt;strong&gt;MS/Windows&lt;/strong&gt;)&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#pnote-613-4&quot; id=&quot;rev-pnote-613-4&quot;&gt;4&lt;/a&gt;]&lt;/sup&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Architecture&lt;/h3&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/xinx/archiXINX.png&quot; alt=&quot;Architecture PNG&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Architecture PNG, fév. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;XINX&lt;/strong&gt; est décomposé en plusieurs parties&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la librairie de composant (contenant un gestionnaire de plugin en Qt, un combobox pour choisir une couleur, une liste de valeur avec les boutons pour ajouter ou supprimer des éléments, une barre d'édition pour faciliter l'édition de dossier)&lt;/li&gt;
&lt;li&gt;la librairie principale (externalisant ce qui peut être nécessaire aux plugins).&lt;/li&gt;
&lt;li&gt;une série de plugin permettant, dans &lt;strong&gt;XINX&lt;/strong&gt; de
&lt;ul&gt;
&lt;li&gt;gérer CVS&lt;/li&gt;
&lt;li&gt;gérer SubVersion&lt;/li&gt;
&lt;li&gt;gérer les extentions XSL, JS, XML, HTML&lt;/li&gt;
&lt;li&gt;gérer les WebServices&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;l'application elle-même&lt;/li&gt;
&lt;li&gt;une application de migration de projet (pour migrer les fichiers projets &lt;strong&gt;XINX&lt;/strong&gt; quand ces derniers changent)&lt;/li&gt;
&lt;li&gt;une librairie gérant l'éditeur de code (l'éditeur utilisé pour la prochaine version est &lt;a href=&quot;http://qcodeedit.edyuk.org/&quot; hreflang=&quot;fr&quot;&gt;QCodeEdit&lt;/a&gt;&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#pnote-613-5&quot; id=&quot;rev-pnote-613-5&quot;&gt;5&lt;/a&gt;]&lt;/sup&gt;)&lt;/li&gt;
&lt;li&gt;les librairies du framework &lt;em&gt;Qt&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vous pouvez une documentation sur l'écriture de &lt;a href=&quot;http://xinx.shadoware.org/wiki/XinxPlugins&quot; hreflang=&quot;fr&quot;&gt;plugins&lt;/a&gt; sur le site de &lt;strong&gt;&lt;a href=&quot;http://xinx.shadoware.org&quot; hreflang=&quot;fr&quot;&gt;XINX&lt;/a&gt;&lt;/strong&gt;  ainsi qu'une documentation au format &lt;a href=&quot;http://xinx.shadoware.org/doxygen/main.html&quot; hreflang=&quot;en&quot;&gt;Doxygen&lt;/a&gt; des librairies.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#rev-pnote-613-1&quot; id=&quot;pnote-613-1&quot;&gt;1&lt;/a&gt;] &lt;strong&gt;Borland/Delphi 7&lt;/strong&gt; étant limité à la plateforme de Microsoft, et l'application ayant pris dés le début une mauvaise direction (orienté fichier de configuration plutôt que feuille de style)&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#rev-pnote-613-2&quot; id=&quot;pnote-613-2&quot;&gt;2&lt;/a&gt;] &lt;strong&gt;Generix&lt;/strong&gt; est un éditeur de logiciel de gestion d'entreprise, dit &lt;em&gt;ERP&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#rev-pnote-613-3&quot; id=&quot;pnote-613-3&quot;&gt;3&lt;/a&gt;] Un acronyme qui contient l'acronyme même, comme &lt;strong&gt;Gnu&lt;/strong&gt; pour &lt;em&gt;Gnu Is not Unix&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#rev-pnote-613-4&quot; id=&quot;pnote-613-4&quot;&gt;4&lt;/a&gt;] &lt;strong&gt;XINX&lt;/strong&gt; est un logiciel libre non parce que je n'avais pas le choix dû à la double licence de la librairie &lt;em&gt;Qt&lt;/em&gt; mais bien par choix personnelle de développer du logiciel libre sur mon temps personnel.&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#rev-pnote-613-5&quot; id=&quot;pnote-613-5&quot;&gt;5&lt;/a&gt;] QCodeEdit est un éditeur de code écrit pour Qt. Il est très performant, et possède beaucoup de fonctionnalité utile. &lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#comment-form</comments>
      <wfw:comment>http://www.shadoware.org/post/2009/02/18/Contenue-d-un-fichier#comment-form</wfw:comment>
      <wfw:commentRss>http://www.shadoware.org/feed/atom/comments/613</wfw:commentRss>
      </item>
    
  <item>
    <title>Nouvelles fonctionnalités de Qt Designer 4.5</title>
    <link>http://www.shadoware.org/post/2008/10/19/Nouvelles-fonctionnalites-de-Qt-Designer-45</link>
    <guid isPermaLink="false">urn:md5:70738bd05352d99baffe0f66326567aa</guid>
    <pubDate>Sun, 19 Oct 2008 19:24:00 +0200</pubDate>
    <dc:creator>Ulrich Van Den Hekke</dc:creator>
        <category>Logiciels</category>
        <category>nokia</category><category>planet</category><category>qt</category><category>trolltech</category>    
    <description>    &lt;p&gt;Sur &lt;em&gt;&lt;del&gt;Trolltech&lt;/del&gt;Nokia Labs Blogs&lt;/em&gt;, Friedelann Kleint nous présente aujourd'hui les nouvelles fonctionnalités de Qt Designer 4.5&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2008/10/19/Nouvelles-fonctionnalites-de-Qt-Designer-45#pnote-610-1&quot; id=&quot;rev-pnote-610-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Au menu, on peut trouver l'ajout de filtre sur l'éditeur de propriétés ainsi que sur l'inspecteur d'objet (Ce qui peut permettre de sélectionner un composant et d'en modifier les propriétés plus rapidement).&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/qtdesigner4.5/objectinspector.png&quot; alt=&quot;objectinspector.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;objectinspector.png, oct 2008&quot; /&gt;&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/qtdesigner4.5/propertyeditorfilter.png&quot; alt=&quot;propertyeditorfilter.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;propertyeditorfilter.png, oct 2008&quot; /&gt;&lt;/p&gt;


&lt;p&gt;L'arrangement de la boite à outil est également différent&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/qtdesigner4.5/widgetbox_iconmode.png&quot; alt=&quot;widgetbox_iconmode.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;widgetbox_iconmode.png, oct 2008&quot; /&gt;&lt;/p&gt;


&lt;p&gt;De plus il est maintenant possible de&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sélectionner l'objet ancêtre d'un &lt;em&gt;widget&lt;/em&gt; en sélectionnant &lt;em&gt;Select ancestors&lt;/em&gt; du menu contextuel.&lt;/li&gt;
&lt;li&gt;Changer le &lt;em&gt;Layout&lt;/em&gt; sans casser et reconstruire le &lt;em&gt;Layout&lt;/em&gt; de la feuille&lt;/li&gt;
&lt;li&gt;Ajouter facilement une nouvelle ligne au layout (L'action &lt;em&gt;Add form layout row&lt;/em&gt; ouvrant la boite de dialogue ci-dessous)&lt;/li&gt;
&lt;li&gt;Créer des Assistants (&lt;em&gt;Wizard&lt;/em&gt;) linéaires&lt;/li&gt;
&lt;li&gt;Désactiver la traduction de certaine chaîne.&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;http://www.shadoware.org/public/billets/qt/qtdesigner4.5/formlayout.png&quot; alt=&quot;formlayout.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;formlayout.png, oct 2008&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Enfin, pour terminer, comme le dit Friedemann&amp;nbsp;:
&lt;q&gt;The general focus of the 4.5 release is on stability and performance.&lt;/q&gt;
Soit&amp;nbsp;: Le but principal de la version 4.5 est la stabilité et les performances.&lt;/p&gt;


&lt;p&gt;Pour plus de précision, je vous conseille d'aller voir la page d'origine et/ou de télécharger la &lt;em&gt;snapshot&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2008/10/19/Nouvelles-fonctionnalites-de-Qt-Designer-45#rev-pnote-610-1&quot; id=&quot;pnote-610-1&quot;&gt;1&lt;/a&gt;] Référence : &lt;a href=&quot;http://labs.trolltech.com/blogs/2008/10/16/new-features-of-qt-designer-45/&quot; title=&quot;http://labs.trolltech.com/blogs/2008/10/16/new-features-of-qt-designer-45/&quot;&gt;http://labs.trolltech.com/blogs/200...&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://www.shadoware.org/post/2008/10/19/Nouvelles-fonctionnalites-de-Qt-Designer-45#comment-form</comments>
      <wfw:comment>http://www.shadoware.org/post/2008/10/19/Nouvelles-fonctionnalites-de-Qt-Designer-45#comment-form</wfw:comment>
      <wfw:commentRss>http://www.shadoware.org/feed/atom/comments/610</wfw:commentRss>
      </item>
    
  <item>
    <title>QT 4.4.2 puis QT 4.4.3 sont sorties</title>
    <link>http://www.shadoware.org/post/2008/09/29/QT-442-puis-QT-443-est-sortie</link>
    <guid isPermaLink="false">urn:md5:d8ea4848af513b7f9e2ec06ccd707535</guid>
    <pubDate>Mon, 06 Oct 2008 17:02:00 +0200</pubDate>
    <dc:creator>Ulrich Van Den Hekke</dc:creator>
        <category>Logiciels</category>
        <category>nokia</category><category>planet</category><category>qt</category><category>trolltech</category>    
    <description>    &lt;p&gt;En une semaine sont sortie les versions 4.4.2 et 4.4.3 de &lt;em&gt;Qt&lt;/em&gt;.&lt;/p&gt;


&lt;p&gt;La version 4.4.2 corrige de nombreux bugs (dont des fuites mémoires sur la partie &lt;em&gt;XmlPatterns&lt;/em&gt;). Vous pouvez trouver la listes des changements &lt;a href=&quot;http://www.shadoware.org/public/billets/qt/changes-4.4.2&quot;&gt;attachée&lt;/a&gt; au billet, ou dans l'archive &lt;em&gt;Qt&lt;/em&gt; se trouvant sur le site &lt;em&gt;Trolltech&lt;/em&gt;.&lt;/p&gt;


&lt;p&gt;La version 4.4.3&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2008/09/29/QT-442-puis-QT-443-est-sortie#pnote-609-1&quot; id=&quot;rev-pnote-609-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt; modifie chaque entête de fichiers, les icônes, ... pour refléter l'achat de &lt;em&gt;Trolltech&lt;/em&gt; par &lt;em&gt;Nokia&lt;/em&gt;. Par la même occasion le site de &lt;em&gt;Trolltech&lt;/em&gt; a été complètement refait (&lt;a href=&quot;http://trolltech.com&quot; hreflang=&quot;en&quot;&gt;http://trolltech.com&lt;/a&gt;).&lt;/p&gt;


&lt;p&gt;Donc si vous avez la version 4.4.2, il n'est pas nécessaire de récupérer la 4.4.3 (sauf si vous souhaiter absolument la dernière version au nom de Nokia), par contre si vous êtes encore à la version 4.4.0 ou 4.4.1, il peut être intéressant d'installer la dernière version (suivant les fonctionnalités que vous utilisez).&lt;/p&gt;


&lt;p&gt;Enfin, la question, sans réponse, est, est-ce que le site de &lt;em&gt;Trolltech&lt;/em&gt; et de &lt;em&gt;Nokia&lt;/em&gt; vont fusionner ou vont-il rester séparer&lt;sup&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2008/09/29/QT-442-puis-QT-443-est-sortie#pnote-609-2&quot; id=&quot;rev-pnote-609-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;&amp;nbsp;?&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2008/09/29/QT-442-puis-QT-443-est-sortie#rev-pnote-609-1&quot; id=&quot;pnote-609-1&quot;&gt;1&lt;/a&gt;] http://trolltech.com/about/news/qt-4.4.3-released&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://www.shadoware.org/post/2008/09/29/QT-442-puis-QT-443-est-sortie#rev-pnote-609-2&quot; id=&quot;pnote-609-2&quot;&gt;2&lt;/a&gt;] ce dernier est tout de même plus pratique, je trouve&lt;/p&gt;&lt;/div&gt;
</description>
    
          <enclosure url="http://www.shadoware.org/public/billets/qt/changes-4.4.2"
      length="19829" type="text/plain" />
          <enclosure url="http://www.shadoware.org/public/billets/qt/changes-4.4.3"
      length="1221" type="text/plain" />
    
    
          <comments>http://www.shadoware.org/post/2008/09/29/QT-442-puis-QT-443-est-sortie#comment-form</comments>
      <wfw:comment>http://www.shadoware.org/post/2008/09/29/QT-442-puis-QT-443-est-sortie#comment-form</wfw:comment>
      <wfw:commentRss>http://www.shadoware.org/feed/atom/comments/609</wfw:commentRss>
      </item>
    
</channel>
</rss>
