[{"data":1,"prerenderedAt":5899},["ShallowReactive",2],{"post-debian-lenny-est-sortie":3,"related-debian-lenny-est-sortie":183},{"id":4,"title":5,"author":6,"body":7,"category":138,"categorySlug":139,"date":140,"description":13,"excerpt":141,"extension":170,"location":171,"meta":172,"navigation":173,"path":174,"published":173,"seo":175,"slug":176,"stem":177,"tags":178,"timeToRead":181,"__hash__":182},"posts\u002Fposts\u002FLogiciels\u002F2009-02-15-debian-lenny-est-sortie.md","Debian Lenny est sortie","Ulrich Vandenhekke",{"type":8,"value":9,"toc":134},"minimark",[10,14,46,53,62,85,91],[11,12,13],"p",{},"Bonjours à tous,",[11,15,16,17,21,22,25,26,29,30,33,45],{},"Voici la grande nouvelle de ce Week-End :Hier, le jour de la ",[18,19,20],"strong",{},"St\nValentin",", la distribution stable ",[18,23,24],{},"Gnu\u002FDebian"," est passé de ",[18,27,28],{},"Etch","\nà ",[18,31,32],{},"Lenny",[34,35,36],"sup",{},[37,38,44],"a",{"href":39,"ariaDescribedBy":40,"dataFootnoteRef":42,"id":43},"#user-content-fn-1",[41],"footnote-label","","user-content-fnref-1","1",".",[11,47,48],{},[49,50],"img",{"alt":51,"src":52},"Logo","\u002FLogiciels\u002Fdebian-lenny-est-sortie\u002Fdebian-logo.png",[11,54,55,56,58,59,45],{},"Cela annonce donc non seulement une nouvelle version stable de\n",[18,57,24],{}," (ce qui est loin d'arriver tous les jours) mais aussi le\ndéblocage de ",[18,60,61],{},"sid",[11,63,64,65,68,69,77,78,80,81,84],{},"Attention lors des prochaines mises à jour, ",[18,66,67],{},"KDE 4"," (ainsi que les\ndernières versions de tous les logiciels) arrivera doucement sur votre\nbureau",[34,70,71],{},[37,72,76],{"href":73,"ariaDescribedBy":74,"dataFootnoteRef":42,"id":75},"#user-content-fn-2",[41],"user-content-fnref-2","2"," si vous êtes en ",[18,79,61],{}," ou en ",[18,82,83],{},"testing",". Cela va de\nmême pour les dernières versions du noyau qui devrait arriver également.",[11,86,87,88,45],{},"La prochaine, future distribution stable (qui apparaîtra sûrement d'ici\n5 ans) sera ",[18,89,90],{},"squeeze",[92,93,96,102],"section",{"className":94,"dataFootnotes":42},[95],"footnotes",[97,98,101],"h2",{"className":99,"id":41},[100],"sr-only","Footnotes",[103,104,105,122],"ol",{},[106,107,109,114,115],"li",{"id":108},"user-content-fn-1",[37,110,111],{"href":111,"rel":112},"http:\u002F\u002Fblog.ganneff.de\u002Fblog\u002F2009\u002F02\u002F14\u002Flenny-release.html",[113],"nofollow"," ",[37,116,121],{"href":117,"ariaLabel":118,"className":119,"dataFootnoteBackref":42},"#user-content-fnref-1","Back to reference 1",[120],"data-footnote-backref","↩",[106,123,125,114,129],{"id":124},"user-content-fn-2",[37,126,127],{"href":127,"rel":128},"http:\u002F\u002Fpusling.com\u002Fblog\u002F?p=94",[113],[37,130,121],{"href":131,"ariaLabel":132,"className":133,"dataFootnoteBackref":42},"#user-content-fnref-2","Back to reference 2",[120],{"title":42,"searchDepth":135,"depth":135,"links":136},2,[137],{"id":41,"depth":135,"text":101},"Logiciels","logiciels","2009-02-15",{"type":8,"value":142},[143,145,160,164],[11,144,13],{},[11,146,16,147,21,149,25,151,29,153,155,45],{},[18,148,20],{},[18,150,24],{},[18,152,28],{},[18,154,32],{},[34,156,157],{},[37,158,44],{"href":39,"ariaDescribedBy":159,"dataFootnoteRef":42,"id":43},[41],[11,161,162],{},[49,163],{"alt":51,"src":52},[11,165,55,166,58,168,45],{},[18,167,24],{},[18,169,61],{},"md","Lille, France",{},true,"\u002Fpost\u002Fdebian-lenny-est-sortie",{"title":5,"description":13},"debian-lenny-est-sortie","posts\u002FLogiciels\u002F2009-02-15-debian-lenny-est-sortie",[179,180],"debian","kde",1,"EsfsGGVO7y_WEe21bi9WNtGHTe0ADRHkYFuj9haww40",[184,1758,1839,2292,2577,5780],{"id":185,"title":186,"author":6,"body":187,"category":1724,"categorySlug":1725,"date":1726,"description":42,"excerpt":1727,"extension":170,"location":171,"meta":1748,"navigation":173,"path":1749,"published":173,"seo":1750,"slug":1751,"stem":1752,"tags":1753,"timeToRead":569,"__hash__":1757},"posts\u002Fposts\u002FProgrammation\u002F2016-12-10-findsimilarity.md","FindSimilarity - Trouver les différences entre plusieurs vidéos",{"type":8,"value":188,"toc":1712},[189,194,197,200,203,206,212,219,223,226,229,270,273,325,329,332,347,353,361,364,373,376,379,382,824,828,831,840,843,846,872,875,999,1002,1010,1025,1028,1031,1581,1591,1595,1598,1602,1605,1608,1614,1617,1621,1627,1637,1640,1657,1674,1678,1681,1687,1690,1696,1701,1705,1708],[190,191,193],"h3",{"id":192},"introduction","Introduction",[11,195,196],{},"Bonjour,",[11,198,199],{},"Je souhaite vous présenter une petite expérience que je viens d'écrire.",[11,201,202],{},"Cela fait plusieurs années que je souhaitais m'amuser sur la librairie OpenCV mais sans jamais en avoir eu l'utilité. J'ai profité d'avoir un peu de temps libre, pour écrire un petit\nprogramme dont le but est de comparer un ensemble de vidéos.",[11,204,205],{},"Le but est ensuite de dire si dans cet ensemble de vidéos, deux vidéos sont identiques, ou se ressemblent, ou sont trop éloignées.",[11,207,208],{},[209,210,211],"em",{},"J'ai souhaité faire cette expérience par amusement, je n'ai donc pas passé beaucoup de temps sur la qualité du code écrit. Ce dernier aurait pu être mieux découpé, posséder des\ncommentaires, des tests unitaires, ... . Si vous voulez utiliser ce code pour un véritable usage production, n'hésitez pas à améliorer celui ci.",[11,213,214,215,45],{},"Vous pouvez trouver le code source de cette expérience à l'adresse suivante : ",[37,216,217],{"href":217,"rel":218},"https:\u002F\u002Fgogs.shadoware.org\u002FShadowareOrg\u002Ffind-similarity",[113],[190,220,222],{"id":221},"le-jeux-de-données","Le jeux de données",[11,224,225],{},"J'ai pris plusieurs films en DVD que je possède. Possédant un NAS, et une chromecast, j'encode ces DVD au format vidéo et je les y dépose. Malheureusement la qualité est dégradée\npar rapport au DVD.",[11,227,228],{},"Pour constituer le jeu de données, je prends ces films encodés, que je dépose dans un dossier. Je copie certains d'entre eux telquel",[230,231,235],"pre",{"className":232,"code":233,"language":234,"meta":42,"style":42},"language-bash shiki shiki-themes one-dark-pro","mkdir example\ncd example\ncp ..\u002Ffilm1.avi film1_copy.avi\n","bash",[236,237,238,250,258],"code",{"__ignoreMap":42},[239,240,242,246],"span",{"class":241,"line":181},"line",[239,243,245],{"class":244},"sVbv2","mkdir",[239,247,249],{"class":248},"subq3"," example\n",[239,251,252,256],{"class":241,"line":135},[239,253,255],{"class":254},"sjrmR","cd",[239,257,249],{"class":248},[239,259,261,264,267],{"class":241,"line":260},3,[239,262,263],{"class":244},"cp",[239,265,266],{"class":248}," ..\u002Ffilm1.avi",[239,268,269],{"class":248}," film1_copy.avi\n",[11,271,272],{},"J'encode certains de ces films avec une résolution différente :",[230,274,276],{"className":232,"code":275,"language":234,"meta":42,"style":42},"avconv -i film2.m4v  -preset veryslow -s 320x240 film2.320x240.m4v\navconv -i film2.m4v  -preset veryslow -s 640x480 film2.640x480.m4v\n",[236,277,278,305],{"__ignoreMap":42},[239,279,280,283,287,290,293,296,299,302],{"class":241,"line":181},[239,281,282],{"class":244},"avconv",[239,284,286],{"class":285},"sVC51"," -i",[239,288,289],{"class":248}," film2.m4v",[239,291,292],{"class":285},"  -preset",[239,294,295],{"class":248}," veryslow",[239,297,298],{"class":285}," -s",[239,300,301],{"class":248}," 320x240",[239,303,304],{"class":248}," film2.320x240.m4v\n",[239,306,307,309,311,313,315,317,319,322],{"class":241,"line":135},[239,308,282],{"class":244},[239,310,286],{"class":285},[239,312,289],{"class":248},[239,314,292],{"class":285},[239,316,295],{"class":248},[239,318,298],{"class":285},[239,320,321],{"class":248}," 640x480",[239,323,324],{"class":248}," film2.640x480.m4v\n",[190,326,328],{"id":327},"comment-fonctionne-la-comparaison","Comment fonctionne la comparaison",[11,330,331],{},"Avant de parler de la comparaison, parlons des fichiers que nous allons comparer. Le programme va se constituer une liste des fichiers à comparer et pour chaque fichier va lire\nles informations suivantes :",[333,334,335,338,341,344],"ul",{},[106,336,337],{},"la durée du film",[106,339,340],{},"la largeur",[106,342,343],{},"la hauteur",[106,345,346],{},"une miniature du film (utilisée pour comparer à l'oeil les vidéos)",[11,348,349,350,45],{},"Ensuite, une fois les méta-données récupérées, le programe se constitue une liste de paires de fichiers à comparer en sélectionnant les fichiers qui ont une durée identique à +\u002F- 5\nsecondes. Ce paramètre est modifiable au niveau de la constante ",[236,351,352],{},"DELTA_SEC",[11,354,355,356,45],{},"Enfin vient la comparaison pour laquelle je me suis simplement basé sur les exemples du site OpenCV que vous pouvez trouver dans la rubrique\n",[37,357,360],{"href":358,"rel":359},"http:\u002F\u002Fdocs.opencv.org\u002F2.4\u002Fdoc\u002Ftutorials\u002Fhighgui\u002Fvideo-input-psnr-ssim\u002Fvideo-input-psnr-ssim.html",[113],"Video Input with OpenCV and similarity measurement",[11,362,363],{},"J'ai utilisé l'algorithme PSNR (Peak signal-to-noise ratio) pour déterminer si les deux images de la vidéos sont plutôt proches ou éloignées. Cet algorithme calcul la distorsion\nentre deux images. Il est principalement utilisé pour quantifier la performance réalisée par un encodeur lors de la compression d'une vidéo. Une valeur entre 30 et 50 signifie que\nles images sont relativement proches. Plus la valeur est haute, et plus la qualité d'image est conservée entre les deux images. Si la valeur est inférieure à 30 on peut estimer qu'il\ny a une forte chance pour que les images soit différentes.",[11,365,366,367,372],{},"Vous pouvez retrouver les formules utilisées par le calcul sur le site d'OpenCV ou sur la page ",[37,368,371],{"href":369,"rel":370},"https:\u002F\u002Ffr.wikipedia.org\u002Fwiki\u002FPeak_Signal_to_Noise_Ratio",[113],"Wikipedia",". Est-ce que ce\ncalcul est le meilleur pour trouver les images similaires ? Je ne sais pas. Si vous avez d'autres propositions, on peut les tester.",[11,374,375],{},"Sur une vidéo on a une multitude d'images (sur un film d'une heure et demie à 25 images secondes, nous en avons 135 000), on pourrait comparer chaque image de la vidéo pour se faire\nune moyenne, de mon coté j'ai préféré comparer une image au milieu de la vidéo afin de parcourir plus vite les vidéos.",[11,377,378],{},"De la même manière pour m'abstraire de la taille de la vidéo qui peut avoir été modififée, je redimensionne, à tort ou à raison, les deux images à une taille identique\n(arbitrairement: 160x120).",[11,380,381],{},"Je vous présente donc ci-dessous l'algorithme que vous pouvez retrouver sur le site d'OpenCV. J'ai légèrement modifié l'algorithme pour redimensionner les images ainsi que pour\nretourner une valeur de PSNR infiniment grande quand deux vidéos sont identiques.",[230,383,387],{"className":384,"code":385,"language":386,"meta":42,"style":42},"language-cpp shiki shiki-themes one-dark-pro","double getPSNR(const cv::Mat& F1, const cv::Mat& F2) {\n    cv::Mat I1, I2;\n\n    cv::resize(F1, I1, cv::Size(160, 120));\n    cv::resize(F2, I2, cv::Size(160, 120));\n\n    cv::Mat s1;\n    cv::absdiff(I1, I2, s1);   \u002F\u002F |I1 - I2|\n    s1.convertTo(s1, CV_32F);  \u002F\u002F cannot make a square on 8 bits\n    s1 = s1.mul(s1);           \u002F\u002F |I1 - I2|^2\n\n    cv::Scalar s = sum(s1);    \u002F\u002F sum elements per channel\n\n    double sse = s.val[0] + s.val[1] + s.val[2]; \u002F\u002F sum channels\n\n    if( sse \u003C= 1e-10) {        \u002F\u002F for small values return zero\n        return std::numeric_limits\u003Cdouble>::infinity();\n    } else {\n        double mse  = sse \u002F (double)(I1.channels() * I1.total());\n        double psnr = 10.0 * log10((255 * 255) \u002F mse);\n        return psnr;\n    }\n","cpp",[236,388,389,436,441,446,474,496,501,507,522,539,562,567,583,588,650,655,685,711,723,772,810,818],{"__ignoreMap":42},[239,390,391,395,398,402,405,408,412,415,419,422,424,426,428,430,433],{"class":241,"line":181},[239,392,394],{"class":393},"seHd6","double",[239,396,397],{"class":244}," getPSNR",[239,399,401],{"class":400},"sn6KH","(",[239,403,404],{"class":393},"const",[239,406,407],{"class":400}," cv::",[239,409,411],{"class":410},"sU0A5","Mat",[239,413,414],{"class":393},"&",[239,416,418],{"class":417},"s_ZVi"," F1",[239,420,421],{"class":400},", ",[239,423,404],{"class":393},[239,425,407],{"class":400},[239,427,411],{"class":410},[239,429,414],{"class":393},[239,431,432],{"class":417}," F2",[239,434,435],{"class":400},") {\n",[239,437,438],{"class":241,"line":135},[239,439,440],{"class":400},"    cv::Mat I1, I2;\n",[239,442,443],{"class":241,"line":260},[239,444,445],{"emptyLinePlaceholder":173},"\n",[239,447,449,452,455,458,461,463,466,468,471],{"class":241,"line":448},4,[239,450,451],{"class":400},"    cv::",[239,453,454],{"class":244},"resize",[239,456,457],{"class":400},"(F1, I1, cv::",[239,459,460],{"class":244},"Size",[239,462,401],{"class":400},[239,464,465],{"class":285},"160",[239,467,421],{"class":400},[239,469,470],{"class":285},"120",[239,472,473],{"class":400},"));\n",[239,475,477,479,481,484,486,488,490,492,494],{"class":241,"line":476},5,[239,478,451],{"class":400},[239,480,454],{"class":244},[239,482,483],{"class":400},"(F2, I2, cv::",[239,485,460],{"class":244},[239,487,401],{"class":400},[239,489,465],{"class":285},[239,491,421],{"class":400},[239,493,470],{"class":285},[239,495,473],{"class":400},[239,497,499],{"class":241,"line":498},6,[239,500,445],{"emptyLinePlaceholder":173},[239,502,504],{"class":241,"line":503},7,[239,505,506],{"class":400},"    cv::Mat s1;\n",[239,508,510,512,515,518],{"class":241,"line":509},8,[239,511,451],{"class":400},[239,513,514],{"class":244},"absdiff",[239,516,517],{"class":400},"(I1, I2, s1);",[239,519,521],{"class":520},"sV9Aq","   \u002F\u002F |I1 - I2|\n",[239,523,525,528,530,533,536],{"class":241,"line":524},9,[239,526,527],{"class":410},"    s1",[239,529,45],{"class":400},[239,531,532],{"class":244},"convertTo",[239,534,535],{"class":400},"(s1, CV_32F);",[239,537,538],{"class":520},"  \u002F\u002F cannot make a square on 8 bits\n",[239,540,542,545,548,551,553,556,559],{"class":241,"line":541},10,[239,543,544],{"class":400},"    s1 ",[239,546,547],{"class":393},"=",[239,549,550],{"class":410}," s1",[239,552,45],{"class":400},[239,554,555],{"class":244},"mul",[239,557,558],{"class":400},"(s1);",[239,560,561],{"class":520},"           \u002F\u002F |I1 - I2|^2\n",[239,563,565],{"class":241,"line":564},11,[239,566,445],{"emptyLinePlaceholder":173},[239,568,570,573,575,578,580],{"class":241,"line":569},12,[239,571,572],{"class":400},"    cv::Scalar s ",[239,574,547],{"class":393},[239,576,577],{"class":244}," sum",[239,579,558],{"class":400},[239,581,582],{"class":520},"    \u002F\u002F sum elements per channel\n",[239,584,586],{"class":241,"line":585},13,[239,587,445],{"emptyLinePlaceholder":173},[239,589,591,594,597,599,602,604,608,611,614,617,620,622,624,626,628,630,632,634,636,638,640,642,644,647],{"class":241,"line":590},14,[239,592,593],{"class":393},"    double",[239,595,596],{"class":400}," sse ",[239,598,547],{"class":393},[239,600,601],{"class":410}," s",[239,603,45],{"class":400},[239,605,607],{"class":606},"sVyAn","val",[239,609,610],{"class":400},"[",[239,612,613],{"class":285},"0",[239,615,616],{"class":400},"] ",[239,618,619],{"class":393},"+",[239,621,601],{"class":410},[239,623,45],{"class":400},[239,625,607],{"class":606},[239,627,610],{"class":400},[239,629,44],{"class":285},[239,631,616],{"class":400},[239,633,619],{"class":393},[239,635,601],{"class":410},[239,637,45],{"class":400},[239,639,607],{"class":606},[239,641,610],{"class":400},[239,643,76],{"class":285},[239,645,646],{"class":400},"];",[239,648,649],{"class":520}," \u002F\u002F sum channels\n",[239,651,653],{"class":241,"line":652},15,[239,654,445],{"emptyLinePlaceholder":173},[239,656,658,661,664,667,670,673,676,679,682],{"class":241,"line":657},16,[239,659,660],{"class":393},"    if",[239,662,663],{"class":400},"( sse ",[239,665,666],{"class":393},"\u003C=",[239,668,669],{"class":285}," 1",[239,671,672],{"class":606},"e",[239,674,675],{"class":400},"-",[239,677,678],{"class":285},"10",[239,680,681],{"class":400},") {",[239,683,684],{"class":520},"        \u002F\u002F for small values return zero\n",[239,686,688,691,694,697,700,702,705,708],{"class":241,"line":687},17,[239,689,690],{"class":393},"        return",[239,692,693],{"class":400}," std::",[239,695,696],{"class":410},"numeric_limits",[239,698,699],{"class":400},"\u003C",[239,701,394],{"class":393},[239,703,704],{"class":400},">::",[239,706,707],{"class":244},"infinity",[239,709,710],{"class":400},"();\n",[239,712,714,717,720],{"class":241,"line":713},18,[239,715,716],{"class":400},"    } ",[239,718,719],{"class":393},"else",[239,721,722],{"class":400}," {\n",[239,724,726,729,732,734,736,739,742,744,747,750,752,755,758,761,764,766,769],{"class":241,"line":725},19,[239,727,728],{"class":393},"        double",[239,730,731],{"class":400}," mse  ",[239,733,547],{"class":393},[239,735,596],{"class":400},[239,737,738],{"class":393},"\u002F",[239,740,741],{"class":400}," (",[239,743,394],{"class":393},[239,745,746],{"class":400},")(",[239,748,749],{"class":410},"I1",[239,751,45],{"class":400},[239,753,754],{"class":244},"channels",[239,756,757],{"class":400},"() ",[239,759,760],{"class":393},"*",[239,762,763],{"class":410}," I1",[239,765,45],{"class":400},[239,767,768],{"class":244},"total",[239,770,771],{"class":400},"());\n",[239,773,775,777,780,782,785,788,791,794,797,799,802,805,807],{"class":241,"line":774},20,[239,776,728],{"class":393},[239,778,779],{"class":400}," psnr ",[239,781,547],{"class":393},[239,783,784],{"class":285}," 10.0",[239,786,787],{"class":393}," *",[239,789,790],{"class":244}," log10",[239,792,793],{"class":400},"((",[239,795,796],{"class":285},"255",[239,798,787],{"class":393},[239,800,801],{"class":285}," 255",[239,803,804],{"class":400},") ",[239,806,738],{"class":393},[239,808,809],{"class":400}," mse);\n",[239,811,813,815],{"class":241,"line":812},21,[239,814,690],{"class":393},[239,816,817],{"class":400}," psnr;\n",[239,819,821],{"class":241,"line":820},22,[239,822,823],{"class":400},"    }\n",[190,825,827],{"id":826},"optimisation","Optimisation",[11,829,830],{},"La raison qui fait que je voulais m'amuser avec OpenCV c'est qu'il permet de faire ces calculs à l'aide du GPU au lieu du CPU.",[11,832,833,834,839],{},"L'utilisation du GPU permet d'améliorer la vitesse de calcul pour tout ce qui est traitement d'image, ce pour quoi un GPU est prévu pour. Pour plus d'informations sur\nl'utilisation du GPU dans OpenCV peut être trouvé sur la page ",[37,835,838],{"href":836,"rel":837},"http:\u002F\u002Fopencv.org\u002Fplatforms\u002Fcuda.html",[113],"CUDA"," d'OpenCV.",[11,841,842],{},"Le problème est que sur la version de Debian jessie que j'utilise, OpenCV n'est pas compilé avec CUDA, et ne permet donc pas d'utiliser le GPU. J'ai donc dû compiler ma propre\nversion d'OpenCV.",[11,844,845],{},"Pour cela la première étape consiste à récupérer le code source et à se positionner sur la branche que l'on souhaite compiler. Pour ma part je préfère compiler sur la branche 2.4,\nplus proche de la version de Debian.",[230,847,849],{"className":232,"code":848,"language":234,"meta":42,"style":42},"git clone https:\u002F\u002Fgithub.com\u002Fopencv\u002Fopencv.git\ngit checkout 2.4\n",[236,850,851,862],{"__ignoreMap":42},[239,852,853,856,859],{"class":241,"line":181},[239,854,855],{"class":244},"git",[239,857,858],{"class":248}," clone",[239,860,861],{"class":248}," https:\u002F\u002Fgithub.com\u002Fopencv\u002Fopencv.git\n",[239,863,864,866,869],{"class":241,"line":135},[239,865,855],{"class":244},[239,867,868],{"class":248}," checkout",[239,870,871],{"class":285}," 2.4\n",[11,873,874],{},"Viens ensuite la compilation :",[230,876,878],{"className":232,"code":877,"language":234,"meta":42,"style":42},"mkdir build\ncd build\ncmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=\u002Fhome\u002Fphoenix\u002Fusr\u002Flocal  -DENABLE_SSE=ON -DENABLE_SSE2=ON -DENABLE_SSE3=ON -DWITH_TBB=ON -DWITH_1394=ON -DWITH_V4L=ON -DWITH_OPENGL=ON  -DWITH_GTK=ON -DWITH_JASPER=ON -DWITH_JPEG=ON -DWITH_PNG=ON -DWITH_TIFF=ON  -DWITH_OPENEXR=ON -DWITH_PVAPI=ON   -DWITH_EIGEN=ON -DCMAKE_SKIP_RPATH=ON -D WITH_CUDA=ON -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -DWITH_IPP=ON -D CUDA_GENERATION=Auto -D WITH_FFMPEG=ON  ..\u002F\n",[236,879,880,887,893],{"__ignoreMap":42},[239,881,882,884],{"class":241,"line":181},[239,883,245],{"class":244},[239,885,886],{"class":248}," build\n",[239,888,889,891],{"class":241,"line":135},[239,890,255],{"class":254},[239,892,886],{"class":248},[239,894,895,898,901,904,906,909,912,915,918,921,924,927,930,933,936,939,942,945,948,951,954,957,959,962,964,967,969,971,974,976,978,981,983,986,988,991,993,996],{"class":241,"line":260},[239,896,897],{"class":244},"cmake",[239,899,900],{"class":285}," -D",[239,902,903],{"class":248}," CMAKE_BUILD_TYPE=RELEASE",[239,905,900],{"class":285},[239,907,908],{"class":248}," CMAKE_INSTALL_PREFIX=\u002Fhome\u002Fphoenix\u002Fusr\u002Flocal",[239,910,911],{"class":285},"  -DENABLE_SSE=ON",[239,913,914],{"class":285}," -DENABLE_SSE2=ON",[239,916,917],{"class":285}," -DENABLE_SSE3=ON",[239,919,920],{"class":285}," -DWITH_TBB=ON",[239,922,923],{"class":285}," -DWITH_1394=ON",[239,925,926],{"class":285}," -DWITH_V4L=ON",[239,928,929],{"class":285}," -DWITH_OPENGL=ON",[239,931,932],{"class":285},"  -DWITH_GTK=ON",[239,934,935],{"class":285}," -DWITH_JASPER=ON",[239,937,938],{"class":285}," -DWITH_JPEG=ON",[239,940,941],{"class":285}," -DWITH_PNG=ON",[239,943,944],{"class":285}," -DWITH_TIFF=ON",[239,946,947],{"class":285},"  -DWITH_OPENEXR=ON",[239,949,950],{"class":285}," -DWITH_PVAPI=ON",[239,952,953],{"class":285},"   -DWITH_EIGEN=ON",[239,955,956],{"class":285}," -DCMAKE_SKIP_RPATH=ON",[239,958,900],{"class":285},[239,960,961],{"class":248}," WITH_CUDA=ON",[239,963,900],{"class":285},[239,965,966],{"class":248}," ENABLE_FAST_MATH=",[239,968,44],{"class":285},[239,970,900],{"class":285},[239,972,973],{"class":248}," CUDA_FAST_MATH=",[239,975,44],{"class":285},[239,977,900],{"class":285},[239,979,980],{"class":248}," WITH_CUBLAS=",[239,982,44],{"class":285},[239,984,985],{"class":285}," -DWITH_IPP=ON",[239,987,900],{"class":285},[239,989,990],{"class":248}," CUDA_GENERATION=Auto",[239,992,900],{"class":285},[239,994,995],{"class":248}," WITH_FFMPEG=ON",[239,997,998],{"class":248},"  ..\u002F\n",[11,1000,1001],{},"J'active lors de la compilation le maximum d'optimisation dont CUDA. J'active également FFMPEG sans lequel le nombre de fichier reconnu baisse énormément sur ma machine. Après\navoir lancé cmake j'obtiens le résultat suivant :",[230,1003,1008],{"className":1004,"code":1006,"language":1007},[1005],"language-text","-- General configuration for OpenCV 2.4.13.1 =====================================\n--   Version control:               2.4.13.1-48-gac118ae\n--\n--   Platform:\n--     Host:                        Linux 3.16.0-4-amd64 x86_64\n--     CMake:                       3.6.2\n--     CMake generator:             Unix Makefiles\n--     CMake build tool:            \u002Fusr\u002Fbin\u002Fmake\n--     Configuration:               RELEASE\n--\n--   C\u002FC++:\n--     Built as dynamic libs?:      YES\n--     C++ Compiler:                \u002Fusr\u002Fbin\u002Fc++  (ver 4.9.2)\n--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -Wno-array-bounds -Wno-aggressive-loop-optimizations -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -ffunction-sections -O3 -DNDEBUG  -DNDEBUG\n--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -Wno-array-bounds -Wno-aggressive-loop-optimizations -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -ffunction-sections -g  -O0 -DDEBUG -D_DEBUG\n--     C Compiler:                  \u002Fusr\u002Fbin\u002Fcc\n--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -Wno-array-bounds -Wno-aggressive-loop-optimizations -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -ffunction-sections -O3 -DNDEBUG  -DNDEBUG\n--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -Wno-array-bounds -Wno-aggressive-loop-optimizations -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -ffunction-sections -g  -O0 -DDEBUG -D_DEBUG\n--     Linker flags (Release):\n--     Linker flags (Debug):\n--     ccache:                      NO\n--     Precompiled headers:         YES\n--\n--   OpenCV modules:\n--     To be built:                 core flann imgproc highgui features2d calib3d ml video legacy objdetect photo gpu ocl nonfree contrib java python stitching superres ts videostab\n--     Disabled:                    world\n--     Disabled by dependency:      -\n--     Unavailable:                 androidcamera dynamicuda viz\n--\n--   GUI:\n--     QT:                          NO\n--     GTK+ 2.x:                    YES (ver 2.24.25)\n--     GThread :                    YES (ver 2.42.1)\n--     GtkGlExt:                    NO\n--     OpenGL support:              NO\n--     VTK support:                 NO\n--\n--   Media I\u002FO:\n--     ZLib:                        \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibz.so (ver 1.2.8)\n--     JPEG:                        \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibjpeg.so (ver )\n--     PNG:                         \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibpng.so (ver 1.2.50)\n--     TIFF:                        \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibtiff.so (ver 42 - 4.0.3)\n--     JPEG 2000:                   \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibjasper.so (ver 1.900.1)\n--     OpenEXR:                     \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibImath.so \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibIlmImf.so \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibIex.so \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibHalf.so \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibIlmThread.so (ver 1.6.1)\n--\n--   Video I\u002FO:\n--     DC1394 1.x:                  NO\n--     DC1394 2.x:                  YES (ver 2.2.3)\n--     FFMPEG:                      YES\n--       codec:                     YES (ver 56.1.0)\n--       format:                    YES (ver 56.1.0)\n--       util:                      YES (ver 54.3.0)\n--       swscale:                   YES (ver 3.0.0)\n--       resample:                  YES (ver 2.1.0)\n--       gentoo-style:              YES\n--     GStreamer:                   NO\n--     OpenNI:                      NO\n--     OpenNI PrimeSensor Modules:  NO\n--     PvAPI:                       NO\n--     GigEVisionSDK:               NO\n--     UniCap:                      NO\n--     UniCap ucil:                 NO\n--     V4L\u002FV4L2:                    NO\u002FYES\n--     XIMEA:                       NO\n--     Xine:                        NO\n--\n--   Other third-party libraries:\n--     Use IPP:                     IPP not found\n--     Use Eigen:                   NO\n--     Use TBB:                     NO\n--     Use OpenMP:                  NO\n--     Use GCD                      NO\n--     Use Concurrency              NO\n--     Use C=:                      NO\n--     Use Cuda:                    YES (ver 7.5)\n--     Use OpenCL:                  YES\n--\n--   NVIDIA CUDA\n--     Use CUFFT:                   YES\n--     Use CUBLAS:                  YES\n--     USE NVCUVID:                 NO\n--     NVIDIA GPU arch:             21\n--     NVIDIA PTX archs:\n--     Use fast math:               YES\n--     Tiny gpu module:             NO\n--\n--   OpenCL:\n--     Version:                     dynamic\n--     Include path:                \u002Fhome\u002Fphoenix\u002FDeveloppement\u002FExternalSoftware\u002Fopencv\u002F3rdparty\u002Finclude\u002Fopencl\u002F1.2\n--     Use AMD FFT:                 NO\n--     Use AMD BLAS:                NO\n--\n--   Python:\n--     Interpreter:                 \u002Fusr\u002Fbin\u002Fpython2 (ver 2.7.10)\n--     Libraries:                   \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibpython2.7.so (ver 2.7.10rc1)\n--     numpy:                       \u002Fusr\u002Flib\u002Fpython2.7\u002Fdist-packages\u002Fnumpy\u002Fcore\u002Finclude (ver 1.8.2)\n--     packages path:               lib\u002Fpython2.7\u002Fdist-packages\n--\n--   Java:\n--     ant:                         \u002Fusr\u002Fbin\u002Fant (ver 1.9.4)\n--     JNI:                         \u002Fusr\u002Flib\u002Fjvm\u002Fjava-7-openjdk-amd64\u002Finclude \u002Fusr\u002Flib\u002Fjvm\u002Fjava-7-openjdk-amd64\u002Finclude \u002Fusr\u002Flib\u002Fjvm\u002Fjava-7-openjdk-amd64\u002Finclude\n--     Java tests:                  YES\n--\n--   Documentation:\n--     Build Documentation:         NO\n--     Sphinx:                      NO\n--     PdfLaTeX compiler:           \u002Fusr\u002Fbin\u002Fpdflatex\n--     Doxygen:                     YES (\u002Fusr\u002Fbin\u002Fdoxygen)\n--\n--   Tests and samples:\n--     Tests:                       YES\n--     Performance tests:           YES\n--     C\u002FC++ Examples:              NO\n--\n--   Install path:                  \u002Fhome\u002Fphoenix\u002Fusr\u002Flocal\n--\n--   cvconfig.h is in:              \u002Fhome\u002Fphoenix\u002FDeveloppement\u002FExternalSoftware\u002Fopencv\u002Fbuild\n-- -----------------------------------------------------------------\n","text",[236,1009,1006],{"__ignoreMap":42},[11,1011,1012,1013,1016,1017,1020,1021,1024],{},"Pour que la compilation se déroule sans problème, il vous faudra installer certains paquets sur votre distribution. Sur Debian Jessie, j'ai installé ",[236,1014,1015],{},"nvidia-cuda-toolkit"," en\nversion ",[236,1018,1019],{},"7.5.18-4~bpo8+1",". Comme vous pouvez les voir c'est une version qui provient du repository de backports. La version ",[236,1022,1023],{},"6.0.37-5"," ne me permettait pas d'activer CUDA. J'ai\ndonc du monter l'ensemble du driver propriétaire sur mon poste de développement.",[11,1026,1027],{},"Rasssurez-vous, si vous ne voulez pas utiliser les backports ou ne pas utiliser de driver propriétaire, vous pouvez tester le programme dans sa version CPU. :)",[11,1029,1030],{},"Voici comment le code a été ré-écrit pour utiliser le GPU à la place du CPU:",[230,1032,1034],{"className":384,"code":1033,"language":386,"meta":42,"style":42},"struct BufferPSNR {                                    \u002F\u002F Optimized GPU versions\n    \u002F\u002F Data allocations are very expensive on GPU. Use a buffer to solve: allocate once reuse later.\n    cv::gpu::GpuMat gF1, gF2, gI1, gI2, gs, t1,t2;\n\n    cv::gpu::GpuMat buf;\n};\n\ndouble getPSNR_GPU_optimized(const cv::Mat& F1, const cv::Mat& F2, BufferPSNR& b) {\n    b.gF1.upload(F1);\n    b.gF2.upload(F2);\n\n    cv::gpu::resize(b.gF1, b.gI1, cv::Size(160, 120));\n    cv::gpu::resize(b.gF2, b.gI2, cv::Size(160, 120));\n\n    b.gI1.convertTo(b.t1, CV_32F);\n    b.gI2.convertTo(b.t2, CV_32F);\n\n    cv::gpu::absdiff(b.t1.reshape(1), b.t2.reshape(1), b.gs);\n    cv::gpu::multiply(b.gs, b.gs, b.gs);\n\n    double sse = cv::gpu::sum(b.gs, b.buf)[0];\n\n    if( sse \u003C= 1e-10) \u002F\u002F for small values return zero\n        return std::numeric_limits\u003Cdouble>::infinity();\n    else {\n        double mse = sse \u002F(double)(F1.channels() * F1.total());\n        double psnr = 10.0*log10((255*255)\u002Fmse);\n        return psnr;\n    }\n}\n",[236,1035,1036,1050,1055,1060,1064,1069,1074,1078,1121,1139,1155,1159,1204,1245,1249,1273,1296,1300,1356,1393,1397,1439,1443,1466,1485,1493,1532,1563,1570,1575],{"__ignoreMap":42},[239,1037,1038,1041,1044,1047],{"class":241,"line":181},[239,1039,1040],{"class":393},"struct",[239,1042,1043],{"class":410}," BufferPSNR",[239,1045,1046],{"class":400}," {",[239,1048,1049],{"class":520},"                                    \u002F\u002F Optimized GPU versions\n",[239,1051,1052],{"class":241,"line":135},[239,1053,1054],{"class":520},"    \u002F\u002F Data allocations are very expensive on GPU. Use a buffer to solve: allocate once reuse later.\n",[239,1056,1057],{"class":241,"line":260},[239,1058,1059],{"class":400},"    cv::gpu::GpuMat gF1, gF2, gI1, gI2, gs, t1,t2;\n",[239,1061,1062],{"class":241,"line":448},[239,1063,445],{"emptyLinePlaceholder":173},[239,1065,1066],{"class":241,"line":476},[239,1067,1068],{"class":400},"    cv::gpu::GpuMat buf;\n",[239,1070,1071],{"class":241,"line":498},[239,1072,1073],{"class":400},"};\n",[239,1075,1076],{"class":241,"line":503},[239,1077,445],{"emptyLinePlaceholder":173},[239,1079,1080,1082,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103,1105,1107,1109,1111,1114,1116,1119],{"class":241,"line":509},[239,1081,394],{"class":393},[239,1083,1084],{"class":244}," getPSNR_GPU_optimized",[239,1086,401],{"class":400},[239,1088,404],{"class":393},[239,1090,407],{"class":400},[239,1092,411],{"class":410},[239,1094,414],{"class":393},[239,1096,418],{"class":417},[239,1098,421],{"class":400},[239,1100,404],{"class":393},[239,1102,407],{"class":400},[239,1104,411],{"class":410},[239,1106,414],{"class":393},[239,1108,432],{"class":417},[239,1110,421],{"class":400},[239,1112,1113],{"class":410},"BufferPSNR",[239,1115,414],{"class":393},[239,1117,1118],{"class":417}," b",[239,1120,435],{"class":400},[239,1122,1123,1126,1128,1131,1133,1136],{"class":241,"line":524},[239,1124,1125],{"class":410},"    b",[239,1127,45],{"class":400},[239,1129,1130],{"class":410},"gF1",[239,1132,45],{"class":400},[239,1134,1135],{"class":244},"upload",[239,1137,1138],{"class":400},"(F1);\n",[239,1140,1141,1143,1145,1148,1150,1152],{"class":241,"line":541},[239,1142,1125],{"class":410},[239,1144,45],{"class":400},[239,1146,1147],{"class":410},"gF2",[239,1149,45],{"class":400},[239,1151,1135],{"class":244},[239,1153,1154],{"class":400},"(F2);\n",[239,1156,1157],{"class":241,"line":564},[239,1158,445],{"emptyLinePlaceholder":173},[239,1160,1161,1163,1166,1169,1171,1173,1176,1178,1180,1182,1184,1186,1189,1192,1194,1196,1198,1200,1202],{"class":241,"line":569},[239,1162,451],{"class":400},[239,1164,1165],{"class":410},"gpu",[239,1167,1168],{"class":400},"::",[239,1170,454],{"class":244},[239,1172,401],{"class":400},[239,1174,1175],{"class":410},"b",[239,1177,45],{"class":400},[239,1179,1130],{"class":606},[239,1181,421],{"class":400},[239,1183,1175],{"class":410},[239,1185,45],{"class":400},[239,1187,1188],{"class":606},"gI1",[239,1190,1191],{"class":400},", cv::",[239,1193,460],{"class":244},[239,1195,401],{"class":400},[239,1197,465],{"class":285},[239,1199,421],{"class":400},[239,1201,470],{"class":285},[239,1203,473],{"class":400},[239,1205,1206,1208,1210,1212,1214,1216,1218,1220,1222,1224,1226,1228,1231,1233,1235,1237,1239,1241,1243],{"class":241,"line":585},[239,1207,451],{"class":400},[239,1209,1165],{"class":410},[239,1211,1168],{"class":400},[239,1213,454],{"class":244},[239,1215,401],{"class":400},[239,1217,1175],{"class":410},[239,1219,45],{"class":400},[239,1221,1147],{"class":606},[239,1223,421],{"class":400},[239,1225,1175],{"class":410},[239,1227,45],{"class":400},[239,1229,1230],{"class":606},"gI2",[239,1232,1191],{"class":400},[239,1234,460],{"class":244},[239,1236,401],{"class":400},[239,1238,465],{"class":285},[239,1240,421],{"class":400},[239,1242,470],{"class":285},[239,1244,473],{"class":400},[239,1246,1247],{"class":241,"line":590},[239,1248,445],{"emptyLinePlaceholder":173},[239,1250,1251,1253,1255,1257,1259,1261,1263,1265,1267,1270],{"class":241,"line":652},[239,1252,1125],{"class":410},[239,1254,45],{"class":400},[239,1256,1188],{"class":410},[239,1258,45],{"class":400},[239,1260,532],{"class":244},[239,1262,401],{"class":400},[239,1264,1175],{"class":410},[239,1266,45],{"class":400},[239,1268,1269],{"class":606},"t1",[239,1271,1272],{"class":400},", CV_32F);\n",[239,1274,1275,1277,1279,1281,1283,1285,1287,1289,1291,1294],{"class":241,"line":657},[239,1276,1125],{"class":410},[239,1278,45],{"class":400},[239,1280,1230],{"class":410},[239,1282,45],{"class":400},[239,1284,532],{"class":244},[239,1286,401],{"class":400},[239,1288,1175],{"class":410},[239,1290,45],{"class":400},[239,1292,1293],{"class":606},"t2",[239,1295,1272],{"class":400},[239,1297,1298],{"class":241,"line":687},[239,1299,445],{"emptyLinePlaceholder":173},[239,1301,1302,1304,1306,1308,1310,1312,1314,1316,1318,1320,1323,1325,1327,1330,1332,1334,1336,1338,1340,1342,1344,1346,1348,1350,1353],{"class":241,"line":713},[239,1303,451],{"class":400},[239,1305,1165],{"class":410},[239,1307,1168],{"class":400},[239,1309,514],{"class":244},[239,1311,401],{"class":400},[239,1313,1175],{"class":410},[239,1315,45],{"class":400},[239,1317,1269],{"class":410},[239,1319,45],{"class":400},[239,1321,1322],{"class":244},"reshape",[239,1324,401],{"class":400},[239,1326,44],{"class":285},[239,1328,1329],{"class":400},"), ",[239,1331,1175],{"class":410},[239,1333,45],{"class":400},[239,1335,1293],{"class":410},[239,1337,45],{"class":400},[239,1339,1322],{"class":244},[239,1341,401],{"class":400},[239,1343,44],{"class":285},[239,1345,1329],{"class":400},[239,1347,1175],{"class":410},[239,1349,45],{"class":400},[239,1351,1352],{"class":606},"gs",[239,1354,1355],{"class":400},");\n",[239,1357,1358,1360,1362,1364,1367,1369,1371,1373,1375,1377,1379,1381,1383,1385,1387,1389,1391],{"class":241,"line":725},[239,1359,451],{"class":400},[239,1361,1165],{"class":410},[239,1363,1168],{"class":400},[239,1365,1366],{"class":244},"multiply",[239,1368,401],{"class":400},[239,1370,1175],{"class":410},[239,1372,45],{"class":400},[239,1374,1352],{"class":606},[239,1376,421],{"class":400},[239,1378,1175],{"class":410},[239,1380,45],{"class":400},[239,1382,1352],{"class":606},[239,1384,421],{"class":400},[239,1386,1175],{"class":410},[239,1388,45],{"class":400},[239,1390,1352],{"class":606},[239,1392,1355],{"class":400},[239,1394,1395],{"class":241,"line":774},[239,1396,445],{"emptyLinePlaceholder":173},[239,1398,1399,1401,1403,1405,1407,1409,1411,1414,1416,1418,1420,1422,1424,1426,1428,1431,1434,1436],{"class":241,"line":812},[239,1400,593],{"class":393},[239,1402,596],{"class":400},[239,1404,547],{"class":393},[239,1406,407],{"class":400},[239,1408,1165],{"class":410},[239,1410,1168],{"class":400},[239,1412,1413],{"class":244},"sum",[239,1415,401],{"class":400},[239,1417,1175],{"class":410},[239,1419,45],{"class":400},[239,1421,1352],{"class":606},[239,1423,421],{"class":400},[239,1425,1175],{"class":410},[239,1427,45],{"class":400},[239,1429,1430],{"class":606},"buf",[239,1432,1433],{"class":400},")[",[239,1435,613],{"class":285},[239,1437,1438],{"class":400},"];\n",[239,1440,1441],{"class":241,"line":820},[239,1442,445],{"emptyLinePlaceholder":173},[239,1444,1446,1448,1450,1452,1454,1456,1458,1460,1463],{"class":241,"line":1445},23,[239,1447,660],{"class":393},[239,1449,663],{"class":400},[239,1451,666],{"class":393},[239,1453,669],{"class":285},[239,1455,672],{"class":606},[239,1457,675],{"class":400},[239,1459,678],{"class":285},[239,1461,1462],{"class":400},")",[239,1464,1465],{"class":520}," \u002F\u002F for small values return zero\n",[239,1467,1469,1471,1473,1475,1477,1479,1481,1483],{"class":241,"line":1468},24,[239,1470,690],{"class":393},[239,1472,693],{"class":400},[239,1474,696],{"class":410},[239,1476,699],{"class":400},[239,1478,394],{"class":393},[239,1480,704],{"class":400},[239,1482,707],{"class":244},[239,1484,710],{"class":400},[239,1486,1488,1491],{"class":241,"line":1487},25,[239,1489,1490],{"class":393},"    else",[239,1492,722],{"class":400},[239,1494,1496,1498,1501,1503,1505,1507,1509,1511,1513,1516,1518,1520,1522,1524,1526,1528,1530],{"class":241,"line":1495},26,[239,1497,728],{"class":393},[239,1499,1500],{"class":400}," mse ",[239,1502,547],{"class":393},[239,1504,596],{"class":400},[239,1506,738],{"class":393},[239,1508,401],{"class":400},[239,1510,394],{"class":393},[239,1512,746],{"class":400},[239,1514,1515],{"class":410},"F1",[239,1517,45],{"class":400},[239,1519,754],{"class":244},[239,1521,757],{"class":400},[239,1523,760],{"class":393},[239,1525,418],{"class":410},[239,1527,45],{"class":400},[239,1529,768],{"class":244},[239,1531,771],{"class":400},[239,1533,1535,1537,1539,1541,1543,1545,1548,1550,1552,1554,1556,1558,1560],{"class":241,"line":1534},27,[239,1536,728],{"class":393},[239,1538,779],{"class":400},[239,1540,547],{"class":393},[239,1542,784],{"class":285},[239,1544,760],{"class":393},[239,1546,1547],{"class":244},"log10",[239,1549,793],{"class":400},[239,1551,796],{"class":285},[239,1553,760],{"class":393},[239,1555,796],{"class":285},[239,1557,1462],{"class":400},[239,1559,738],{"class":393},[239,1561,1562],{"class":400},"mse);\n",[239,1564,1566,1568],{"class":241,"line":1565},28,[239,1567,690],{"class":393},[239,1569,817],{"class":400},[239,1571,1573],{"class":241,"line":1572},29,[239,1574,823],{"class":400},[239,1576,1578],{"class":241,"line":1577},30,[239,1579,1580],{"class":400},"}\n",[11,1582,1583,1584,1586,1587,1590],{},"L'utilisation de la structure ",[236,1585,1113],{}," permet de ne pas perdre de performance lors de l'initialisation relativement lourde des objets ",[236,1588,1589],{},"GpuMat",". Sans cela, l'utilisation du Gpu\nserait moins performant que la version Cpu.",[190,1592,1594],{"id":1593},"lexpérience","L'expérience",[11,1596,1597],{},"Maintenant place à l'expérience. Nous allons lancer notre programme sur notre jeu d'essai comprenant les vidéos issue des DVD, ainsi que les vidéos recompressées pour l'expérience.\nSi l'expérence se déroule bien l'algorithme devrait nous detecter les fichiers dupliqués, ainsi que les fichiers recompressés.",[97,1599,1601],{"id":1600},"lancement-et-selection-des-dossiers","Lancement et selection des dossiers",[11,1603,1604],{},"La première étape est la sélection des dossiers que l'on souhaite comparer. Le programme ira lire récursivement l'ensemble des dossiers pour y trouver l'ensemble des fichiers\nvidéos.",[11,1606,1607],{},"La sélection d'un projet provient de mon envie de départ de pouvoir enregistrer l'avancement du projet au fur et à mesure. Cette étape n'a pas été réalisée mais l'existance du mode\nprojet existe toujours.",[11,1609,1610],{},[49,1611],{"alt":1612,"src":1613},"Selection du projet","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-1.png",[11,1615,1616],{},"Une fois le dossier projet choisi, il faut sélectionner la liste des dossiers contenant les vidéos et lancer le programme ...",[97,1618,1620],{"id":1619},"comparaison-des-vidéos","Comparaison des vidéos",[11,1622,1623,1624,45],{},"Dans cette étape le programme compare l'ensemble des vidéos présentes dans les dossiers. L'ensemble du processus tourne dans des threads afin de ne pas figer l'IHM, grâce à l'API\n",[236,1625,1626],{},"QtConcurrent",[11,1628,1629,1633],{},[49,1630],{"alt":1631,"src":1632},"Recherche","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-2.png",[49,1634],{"alt":1635,"src":1636},"Recherche encore","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-3.png",[11,1638,1639],{},"Les étapes de la recherche sont donc :",[333,1641,1642,1645,1648,1651,1654],{},[106,1643,1644],{},"Constitution de la liste des fichiers",[106,1646,1647],{},"Récupération des méta-données",[106,1649,1650],{},"Création de la liste des paires de fichiers (en filtrant sur la durée)",[106,1652,1653],{},"Calcul du PSNR pour chaque paire de fichiers",[106,1655,1656],{},"Filtrage pour ne garder que les paires de fichiers dont le PSNR est supérieur à 30 db.",[11,1658,1659,1660,1662,1663,1665,1666,1669,1670,1673],{},"Lors de mon développement je me suis basé sur l'API ",[236,1661,1626],{}," pour faire les différentes étapes. Faisant beaucoup de développement NodeJS ces derniers temps je suis habitué à\nl'utilisation des promesses et de leur enchainement pour faire des processus complexes. J'ai trouvé dommage de ne pas retrouver la même chose dans l'API ",[236,1664,1626],{},". Pour\nreproduire un équivalent, lorsqu'un ",[236,1667,1668],{},"QFuture","se termine, le signal émis par ",[236,1671,1672],{},"QFutureWatcher"," est récupérer par un SLOT du moteur qui s'occupe de lancer l'étape suivante.",[97,1675,1677],{"id":1676},"la-page-de-résultat","La page de résultat",[11,1679,1680],{},"La page de résultat liste les vidéos considérées identiques suite à l'étude d'une des images. Un coup d'oeil visuel permet alors de se faire un avis sur la question, et de\nsupprimer la vidéo que l'on souhaite.",[11,1682,1683],{},[49,1684],{"alt":1685,"src":1686},"Résultat 1","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-4.png",[11,1688,1689],{},"Comme on peut le voir le programme retrouve les vidéos dont l'image est identique, ainsi que les films qui ont été redimensionnés sans trop de soucis.\nLe problème se situe alors au niveau du bruit qui est généré. Plusieurs films sont considérés comme proches alors que complètement différents. Pour régler ce problème, comparer\nplusieurs images d'une même vidéo à des timestamps différents pourrait peut-être régler le problème.",[11,1691,1692],{},[49,1693],{"alt":1694,"src":1695},"Résultat 2","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-5.png",[11,1697,1698],{},[18,1699,1700],{},"Je vous conseille de vérifier manuellement la qualité et la similarité de chaque vidéo manuellement avant toute suppression.",[190,1702,1704],{"id":1703},"conclusion","Conclusion",[11,1706,1707],{},"En conclusion, j'ai trouvé l'expérience intéressante, et maintenant qu'elle est terminée, je vais pouvoir en tenter une autre ;). Est-ce que le programme continuera d'évoluer ?\nPourquoi pas ? Cela dépendera des PR (Pull Request) et des demandes faites par les utilisateurs, ainsi que du temps que j'ai envie de passer dessus.",[1709,1710,1711],"style",{},"html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}",{"title":42,"searchDepth":135,"depth":135,"links":1713},[1714,1715,1716,1717,1718,1719,1720,1721],{"id":192,"depth":260,"text":193},{"id":221,"depth":260,"text":222},{"id":327,"depth":260,"text":328},{"id":826,"depth":260,"text":827},{"id":1593,"depth":260,"text":1594},{"id":1600,"depth":135,"text":1601},{"id":1619,"depth":135,"text":1620},{"id":1676,"depth":135,"text":1677,"children":1722},[1723],{"id":1703,"depth":260,"text":1704},"Programmation","programmation","2016-12-10",{"type":8,"value":1728},[1729,1731,1733,1735,1737,1739,1743],[190,1730,193],{"id":192},[11,1732,196],{},[11,1734,199],{},[11,1736,202],{},[11,1738,205],{},[11,1740,1741],{},[209,1742,211],{},[11,1744,214,1745,45],{},[37,1746,217],{"href":217,"rel":1747},[113],{"planet":173},"\u002Fpost\u002Ffindsimilarity",{"title":186,"description":42},"findsimilarity","posts\u002FProgrammation\u002F2016-12-10-findsimilarity",[1754,1755,1756,179],"qt","opencv","video","LR-Ko6CoDmyd4rJj7msRVs_pkiaov-yO2_RYmY_C6cE",{"id":1759,"title":1760,"author":6,"body":1761,"category":138,"categorySlug":139,"date":1813,"description":1765,"excerpt":1814,"extension":170,"location":171,"meta":1832,"navigation":173,"path":1833,"published":173,"seo":1834,"slug":1835,"stem":1836,"tags":1837,"timeToRead":135,"__hash__":1838},"posts\u002Fposts\u002FLogiciels\u002F2009-04-11-kde4-devient-instable.md","KDE4 devient instable ...",{"type":8,"value":1762,"toc":1811},[1763,1766,1769,1781,1788,1791,1805,1808],[11,1764,1765],{},"Title: KDE4 devient instable ...\nTags: debian, kde, qt",[11,1767,1768],{},"Titre trolleur, cela ne veux pas dire que KDE 4 est moins stable\nqu'avant mais qu'il a passé une étape supplémentaire chez Debian.",[11,1770,1771,1772,1774,1775,1777,1778,45],{},"Voilà quelques jours déjà que la distribution ",[18,1773,24],{}," intègre\n",[18,1776,67],{}," dans sa version instable. C'est une grande nouvelle car cela\nva permettre à toute les personnes se trouvant en instable et n'ayant\npas touchées à la branche expérimental de Debian de pouvoir tester ",[18,1779,1780],{},"KDE\n4",[11,1782,1783,1784,1787],{},"Malheureusement pour les ",[209,1785,1786],{},"traumatisé de KDE 4",", l'intégration de ce\ndernier remplace KDE 3.5 et ne viens pas se positionner en parallèle. Il\nme semble pourtant que lors du passage de KDE 2 à KDE 3, il était\npossible d'avoir les deux bureaux en même temps sur sa machine et de\nswitcher de l'un à l'autre sans difficulté. Cela signifie donc peut-être\naussi la perte d'utilisateur pour KDE sous Gnu\u002FDebian au profit d'un\nautre environnement de bureau.",[11,1789,1790],{},"Afin d'effectuer la migration en douceur, Gnu\u002FDebian propose un\nassistant de migration de KDE du nom de Kaboom. Cet assistant, démarrer\nlors de la première connexion de l'utilisateur et vous propose alors de\nsauvegarder votre ancien dossier de configuration KDE 3 et de migrer le\ndossier .kde vers la version 4.",[11,1792,1793,1797,1801],{},[49,1794],{"alt":1795,"src":1796},"kaboom1","\u002FLogiciels\u002Fkde4-devient-instable\u002Fkaboom1_s.jpg",[49,1798],{"alt":1799,"src":1800},"kaboom2","\u002FLogiciels\u002Fkde4-devient-instable\u002Fkaboom2_s.jpg",[49,1802],{"alt":1803,"src":1804},"kaboom3","\u002FLogiciels\u002Fkde4-devient-instable\u002Fkaboom3_s.jpg",[11,1806,1807],{},"Je viens donc de passer à KDE 4 et m'émerveille des nouvelles\nfonctionnalités de KWin (cube, placement des fenêtres) que je n'avais\npas avant, car n'avait jamais installé Compiz ...",[11,1809,1810],{},"Bonne installation,",{"title":42,"searchDepth":135,"depth":135,"links":1812},[],"2009-04-11",{"type":8,"value":1815},[1816,1818,1820,1828],[11,1817,1765],{},[11,1819,1768],{},[11,1821,1771,1822,1774,1824,1777,1826,45],{},[18,1823,24],{},[18,1825,67],{},[18,1827,1780],{},[11,1829,1783,1830,1787],{},[209,1831,1786],{},{},"\u002Fpost\u002Fkde4-devient-instable",{"title":1760,"description":1765},"kde4-devient-instable","posts\u002FLogiciels\u002F2009-04-11-kde4-devient-instable",[179,180,1754],"Oj3jqh3sY77Ym6LYJ2tDQUMs5alVjGgGLz0JxRhI7k8",{"id":1840,"title":1841,"author":6,"body":1842,"category":1855,"categorySlug":2265,"date":2266,"description":42,"excerpt":2267,"extension":170,"location":171,"meta":2283,"navigation":173,"path":2284,"published":173,"seo":2285,"slug":2286,"stem":2287,"tags":2288,"timeToRead":448,"__hash__":2291},"posts\u002Fposts\u002FXINX\u002F2009-03-06-xinx-0.8.0.0.md","XINX 0.8.0.0",{"type":8,"value":1843,"toc":2258},[1844,1850,1856,1864,1867,1875,1878,1881,1885,1896,1903,1906,1911,1917,1934,1938,1944,1947,1950,1954,1959,1967,2154,2164,2168,2171,2179,2183,2188,2200,2203,2207,2210,2216,2219,2249,2255],[11,1845,1846],{},[49,1847],{"alt":1848,"src":1849},"Editeur","\u002FXINX\u002Fxinx-0.8.0.0\u002Fediteur_de_texte.png",[11,1851,1852,1853,45],{},"J'ai le plaisir de vous annoncer la sortie de la nouvelle version de\n",[18,1854,1855],{},"XINX",[11,1857,1858,1860,1861,45],{},[18,1859,1855],{}," est un éditeur de projet web basé sur les technologies XSL,\nHTML, CSS, JavaScript. Il possède un mode projet permettant de dériver\nles projets à la manière des consultants GCE de l'entreprise ",[209,1862,1863],{},"Generix\nGroup",[11,1865,1866],{},"Cette dernière version a mis beaucoup de temps pour sortir et est moins\ncomplète que celle que je souhaitais faire à l'origine. Cela viens de\nplusieurs raison :",[333,1868,1869,1872],{},[106,1870,1871],{},"de gros changement interne",[106,1873,1874],{},"moins de temps le soir et le week-end.",[11,1876,1877],{},"La prochaine version 0.8.1 contiendra les développements que je n'ai pu\nmettre dans cette version. N'hésitez pas à faire un retour sur les\nproblèmes que vous rencontrez pour que ces derniers soit également\ncorriger pour la prochaine version.",[11,1879,1880],{},"Nous allons détailler ci-dessous les différentes amélioration incluse\ndans cette version.",[190,1882,1884],{"id":1883},"qcodeedit-le-nouvel-éditeur","QCodeEdit - Le nouvel éditeur",[11,1886,1887,1888,1891,1892,1895],{},"L'éditeur de texte de cette version a complètement été remplacé. On est\npassé de QTextEdit (",[209,1889,1890],{},"éditeur de texte de Qt Software",") à QCodeEdit\n(",[209,1893,1894],{},"Développé par Luc Bruant aka fullmetalcoder","). Heureusement que les\nAPIs de ces deux éditeurs sont très similaire ce qui a permis\nd'effectuer les changements assez rapidement (quelques mois au lieu de\nquelques années ;) ).",[11,1897,1898,1899,1902],{},"Je tiens également à remercier ",[209,1900,1901],{},"fullmetalcoder"," de sa réactivité sur le\ndéveloppement de QCodeEdit.",[11,1904,1905],{},"Les nouveautés qu'apportent ce nouvel éditeur par rapport à QTextEdit\nsont :",[333,1907,1908],{},[106,1909,1910],{},"le folding",[11,1912,1913],{},[49,1914],{"alt":1915,"src":1916},"Mark","\u002FXINX\u002Fxinx-0.8.0.0\u002Fmarqueur.png",[333,1918,1919,1922,1928,1931],{},[106,1920,1921],{},"les couleurs de fond sur les marque pages et les erreurs (pour une\nplus grande clarté).",[106,1923,1924,1925,1462],{},"un chargement plus rapide des fichiers (exemple :\n",[236,1926,1927],{},"configuration.xml",[106,1929,1930],{},"pourvoir faire des sélections verticales (à l'aide de Ctrl+Shift)\ncomme le font certain éditeurs",[106,1932,1933],{},"afficher les correspondances de parenthèses",[190,1935,1937],{"id":1936},"test-du-xpath","Test du XPATH",[11,1939,1940],{},[49,1941],{"alt":1942,"src":1943},"X-Quey","\u002FXINX\u002Fxinx-0.8.0.0\u002Fxpath.png",[11,1945,1946],{},"Cette boite de dialogue permet d'exécuter un X-PATH (ou une requête\nXQuery) sur un fichier de présentation. Cela permet de tester rapidement\nles X-PATH compliqué avant de lancer la page sous le navigateur.",[11,1948,1949],{},"Il est possible de saisir des X-PATH relativement à un X-PATH\nsélectionné dans le flux de présentation ou de manière absolu.",[190,1951,1953],{"id":1952},"script-automatique","Script automatique",[11,1955,1956,1958],{},[18,1957,1855],{}," permet également d'appeler un script lors de la sauvegarde d'un\nfichier. Pour cela un nouvel objet permettant de modifier le contenue de\nl'éditeur plus facilement a été créé.Comme exemple à la sauvegarde de\nscript ont été mis à jours :",[333,1960,1961,1964],{},[106,1962,1963],{},"La mise à jours des key('url-param','') par des X-PATH",[106,1965,1966],{},"La mise à jours du nom du fichier dans les feuilles de styles.",[230,1968,1972],{"className":1969,"code":1970,"language":1971,"meta":42,"style":42},"language-javascript shiki shiki-themes one-dark-pro","obj.beforeSave = function() {\n  this.run();\n};\n\nobj.run = function() {\n  var search = new DocumentSearch(textEdit);\n\n  search.options.regExp = true;\n  search.searchText = \"key\\\\('url-param', '(.*)'\\\\)\";\n  search.replaceText =\n    \"\u002Flayout_data\u002Fapplication_data\u002Ftemporaire\u002Fparam[@name='\\\\1']\";\n\n  while (search.next()) {}\n};\n","javascript",[236,1973,1974,1993,2005,2009,2013,2027,2050,2054,2077,2104,2116,2128,2132,2150],{"__ignoreMap":42},[239,1975,1976,1979,1981,1984,1987,1990],{"class":241,"line":181},[239,1977,1978],{"class":410},"obj",[239,1980,45],{"class":400},[239,1982,1983],{"class":244},"beforeSave",[239,1985,1986],{"class":254}," =",[239,1988,1989],{"class":393}," function",[239,1991,1992],{"class":400},"() {\n",[239,1994,1995,1998,2000,2003],{"class":241,"line":135},[239,1996,1997],{"class":410},"  this",[239,1999,45],{"class":400},[239,2001,2002],{"class":244},"run",[239,2004,710],{"class":400},[239,2006,2007],{"class":241,"line":260},[239,2008,1073],{"class":400},[239,2010,2011],{"class":241,"line":448},[239,2012,445],{"emptyLinePlaceholder":173},[239,2014,2015,2017,2019,2021,2023,2025],{"class":241,"line":476},[239,2016,1978],{"class":410},[239,2018,45],{"class":400},[239,2020,2002],{"class":244},[239,2022,1986],{"class":254},[239,2024,1989],{"class":393},[239,2026,1992],{"class":400},[239,2028,2029,2032,2035,2037,2040,2043,2045,2048],{"class":241,"line":498},[239,2030,2031],{"class":393},"  var",[239,2033,2034],{"class":606}," search",[239,2036,1986],{"class":254},[239,2038,2039],{"class":393}," new",[239,2041,2042],{"class":244}," DocumentSearch",[239,2044,401],{"class":400},[239,2046,2047],{"class":606},"textEdit",[239,2049,1355],{"class":400},[239,2051,2052],{"class":241,"line":503},[239,2053,445],{"emptyLinePlaceholder":173},[239,2055,2056,2059,2061,2064,2066,2069,2071,2074],{"class":241,"line":509},[239,2057,2058],{"class":410},"  search",[239,2060,45],{"class":400},[239,2062,2063],{"class":410},"options",[239,2065,45],{"class":400},[239,2067,2068],{"class":606},"regExp",[239,2070,1986],{"class":254},[239,2072,2073],{"class":285}," true",[239,2075,2076],{"class":400},";\n",[239,2078,2079,2081,2083,2086,2088,2091,2094,2097,2099,2102],{"class":241,"line":524},[239,2080,2058],{"class":410},[239,2082,45],{"class":400},[239,2084,2085],{"class":606},"searchText",[239,2087,1986],{"class":254},[239,2089,2090],{"class":248}," \"key",[239,2092,2093],{"class":254},"\\\\",[239,2095,2096],{"class":248},"('url-param', '(.*)'",[239,2098,2093],{"class":254},[239,2100,2101],{"class":248},")\"",[239,2103,2076],{"class":400},[239,2105,2106,2108,2110,2113],{"class":241,"line":541},[239,2107,2058],{"class":410},[239,2109,45],{"class":400},[239,2111,2112],{"class":606},"replaceText",[239,2114,2115],{"class":254}," =\n",[239,2117,2118,2121,2123,2126],{"class":241,"line":564},[239,2119,2120],{"class":248},"    \"\u002Flayout_data\u002Fapplication_data\u002Ftemporaire\u002Fparam[@name='",[239,2122,2093],{"class":254},[239,2124,2125],{"class":248},"1']\"",[239,2127,2076],{"class":400},[239,2129,2130],{"class":241,"line":569},[239,2131,445],{"emptyLinePlaceholder":173},[239,2133,2134,2137,2139,2142,2144,2147],{"class":241,"line":585},[239,2135,2136],{"class":393},"  while",[239,2138,741],{"class":400},[239,2140,2141],{"class":410},"search",[239,2143,45],{"class":400},[239,2145,2146],{"class":244},"next",[239,2148,2149],{"class":400},"()) {}\n",[239,2151,2152],{"class":241,"line":590},[239,2153,1073],{"class":400},[11,2155,2156,2157,2159,2160,2163],{},"La nouveauté se trouve dans l'ajout de quatre nouvelle méthodes. La\nméthode utilisé ici est ",[236,2158,1983],{}," et permet de faire des\nmodifications au texte avant sauvegarde. Tout comme ",[236,2161,2162],{},"afterSave"," permet\nd'effectuer des modifications au texte après sauvegarde. Nous avons\négalement deux méthodes beforeLoad et afterLoad pour les opérations à\nfaire lors de la lecture.",[190,2165,2167],{"id":2166},"autres-nouveautés","Autres nouveautés",[11,2169,2170],{},"Bien sur cet version apporte aussi d'autres nouveautés comme :",[333,2172,2173,2176],{},[106,2174,2175],{},"la fermeture automatique de balise",[106,2177,2178],{},"des nouvelles options, ...",[190,2180,2182],{"id":2181},"installation","Installation",[2184,2185,2187],"h4",{"id":2186},"sous-mswindows","Sous Ms\u002FWindows",[11,2189,2190,2191,2193,2194,2199],{},"Pour installer la dernière version de ",[18,2192,1855],{}," vous pouvez télécharger\nle ",[37,2195,2198],{"href":2196,"rel":2197},"http:\u002F\u002Fxinx.shadoware.org\u002Fdownloads\u002F40",[113],"programme d'installation"," et le lancer. Il remplacera\nautomatiquement l'ancienne version.",[11,2201,2202],{},"Si vous avez des fichiers de données modifiés (template, script, ...)\npensez à les sauvegarder.",[2184,2204,2206],{"id":2205},"sous-gnulinux","Sous Gnu\u002FLinux",[11,2208,2209],{},"Sous Debian, vous pouvez ajouter le dépôt dans le fichier\n\u002Fetc\u002Fapt\u002Fsources.list. Ainsi vous serez automatiquement prévenu des\nmises à jours éventuelle.",[230,2211,2214],{"className":2212,"code":2213,"language":1007},[1005],"deb http:\u002F\u002Fapt.shadoware.org\u002F sid main\n",[236,2215,2213],{"__ignoreMap":42},[11,2217,2218],{},"puis dans une console :",[230,2220,2222],{"className":232,"code":2221,"language":234,"meta":42,"style":42},"sudo apt-cache search xinx\nsudo aptitude install xinx\n",[236,2223,2224,2237],{"__ignoreMap":42},[239,2225,2226,2229,2232,2234],{"class":241,"line":181},[239,2227,2228],{"class":244},"sudo",[239,2230,2231],{"class":248}," apt-cache",[239,2233,2034],{"class":248},[239,2235,2236],{"class":248}," xinx\n",[239,2238,2239,2241,2244,2247],{"class":241,"line":135},[239,2240,2228],{"class":244},[239,2242,2243],{"class":248}," aptitude",[239,2245,2246],{"class":248}," install",[239,2248,2236],{"class":248},[11,2250,2251,2252,2254],{},"Pour les autres distributions ou pour les machines MacOS vous pouvez\ncompiler ",[18,2253,1855],{}," à partir des sources.",[1709,2256,2257],{},"html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":42,"searchDepth":135,"depth":135,"links":2259},[2260,2261,2262,2263,2264],{"id":1883,"depth":260,"text":1884},{"id":1936,"depth":260,"text":1937},{"id":1952,"depth":260,"text":1953},{"id":2166,"depth":260,"text":2167},{"id":2181,"depth":260,"text":2182},"xinx","2009-03-06",{"type":8,"value":2268},[2269,2273,2277],[11,2270,2271],{},[49,2272],{"alt":1848,"src":1849},[11,2274,1852,2275,45],{},[18,2276,1855],{},[11,2278,2279,1860,2281,45],{},[18,2280,1855],{},[209,2282,1863],{},{},"\u002Fpost\u002Fxinx-0.8.0.0",{"title":1841,"description":42},"xinx-0.8.0.0","posts\u002FXINX\u002F2009-03-06-xinx-0.8.0.0",[179,2265,2289,1754,2290],"generix-group","xml","2LVP73RxAuNHiNwoDLW7n9zx61WC1hKRo8CPZUCY5rk",{"id":2293,"title":2294,"author":6,"body":2295,"category":2342,"categorySlug":2543,"date":2544,"description":42,"excerpt":2545,"extension":170,"location":171,"meta":2569,"navigation":173,"path":2570,"published":173,"seo":2571,"slug":2572,"stem":2573,"tags":2574,"timeToRead":260,"__hash__":2576},"posts\u002Fposts\u002FKMDAlert\u002F2011-08-14-kmdalert-0.2.md","KMDAlert - Logiciel de surveillance de périphérique RAID - Version pour KDE 4.0",{"type":8,"value":2296,"toc":2535},[2297,2301,2309,2316,2327,2330,2333,2337,2362,2372,2379,2400,2405,2409,2415,2485,2488,2492,2500,2504,2525,2529,2532],[97,2298,2300],{"id":2299},"présentation","Présentation",[11,2302,2303,2304,2308],{},"Possédant chez moi des disques durs en RAID logiciels sous Gnu\u002FLinux, en\n2007 (cela fait déjà 4 ans), ",[37,2305,2307],{"href":2306},"\u002Fpost\u002F2007-08-17-kmdalert-logiciel-de-surveillance-raid\u002F","j'avais écrit un petit logiciel"," dont le\nbut était de faire du monitoring RAID.",[11,2310,2311,2312,2315],{},"En cas de reconstruction du RAID ou de disque défectueux, le logiciel\naffiche une notification à l'utilisateur, et change le statut affiché\ndans la barre de notification (",[209,2313,2314],{},"systray","). L'icône change bien sur en\nfonction de l'état du RAID :",[333,2317,2318,2321,2324],{},[106,2319,2320],{},"dégradé (avec un point d'exclamation)",[106,2322,2323],{},"en cours de synchronisation (avec une barre de progression)",[106,2325,2326],{},"disque RAID dans un état normal",[11,2328,2329],{},"Ce logiciel ne tournait que sous KDE 3.X.",[11,2331,2332],{},"Voici donc une nouvelle version (qui a mis le temps de sortir) qui est\nun portage de l'application sous KDE 4.X. Elle utilise donc le nouveau\nsystème de notification de KDE (pour l'instant en passant uniquement par\nles notifications standard). Quelques améliorations y seront apportées\nplus tard.",[97,2334,2336],{"id":2335},"requis","Requis",[11,2338,2339,2340,2343,2344,2347,2348,2351,2352,421,2355,2358,2359,2361],{},"Pour fonctionner ",[209,2341,2342],{},"KMDAlert"," nécessite que le dossier ",[236,2345,2346],{},"\u002Fsys"," soit monté\net que ",[236,2349,2350],{},"\u002Fsys\u002Fblock\u002F"," soit renseigné pour chaque volume RAID (exemple\n",[236,2353,2354],{},"\u002Fsys\u002Fblock\u002Fmd0",[236,2356,2357],{},"\u002Fsys\u002Fblock\u002Fmd1",", ...). ",[236,2360,2342],{}," observe ensuite les\nmodifications faites sur les fichiers pour informer l'utilisateur des\nmodifications faites sur le volume RAID ou sur les disques le composant.",[11,2363,2364,2365,2367,2368,2371],{},"De nos jours le dossier ",[236,2366,2346],{}," et ",[236,2369,2370],{},"\u002Fsys\u002Fblock"," devraient être toujours\nprésents.",[11,2373,2374,2375,2378],{},"L'application a été développée sur ",[209,2376,2377],{},"Gnu\u002FDebian Squeeze",", sur un KDE\n4.4.5 avec un noyau 2.6.32.",[11,2380,2381,2383,2384,2387,2388,2390,2391,2393,2394,2396,2397,2399],{},[209,2382,2342],{}," ne nécessite pas de ",[209,2385,2386],{},"Inotify",". ",[209,2389,2342],{}," lit le contenu de\nplusieurs fichiers dans le dossier ",[236,2392,2346],{}," toutes les 6 secondes pour\nêtre informé de la modification de l'état du périphérique. Sur\nl'application d'origine, développé sous un noyau 2.6.18, ",[209,2395,2386],{}," n'est\npas averti des modifications faites sur le système de fichier ",[236,2398,2346],{},".\nLes dates de ces fichiers ne sont pas non plus modifiées. Si quelqu'un a\nune autre méthode à me proposer, je reste ouvert à toutes propositions.",[11,2401,2402,2404],{},[209,2403,2342],{}," est une application écrite en utilisant les librairies de\nKDE, mais devrait tout de même fonctionner sous Gnome. Les messages de\nnotification utilisent donc le système de notification de KDE (bien que\nje n'utilise pas toutes ses possibilités).",[97,2406,2408],{"id":2407},"compilation-installation","Compilation \u002F Installation",[11,2410,2411,2412,2414],{},"La compilation et l'installation de ",[209,2413,2342],{}," se fait à l'aide du trio\nhabituel :",[230,2416,2418],{"className":232,"code":2417,"language":234,"meta":42,"style":42},"# Décompression de KMDAlert\ntar xjfv kmdalert-0.2-77c0d6b4d49f.tar.gz\ncd kmdalert-77c0d6b4d49f\n# Préparation de la compilation\nmkdir build\ncd build\n# Comilation\ncmake ..\u002Fmake\n# Installation\nmake install\n",[236,2419,2420,2425,2436,2443,2448,2454,2460,2465,2472,2477],{"__ignoreMap":42},[239,2421,2422],{"class":241,"line":181},[239,2423,2424],{"class":520},"# Décompression de KMDAlert\n",[239,2426,2427,2430,2433],{"class":241,"line":135},[239,2428,2429],{"class":244},"tar",[239,2431,2432],{"class":248}," xjfv",[239,2434,2435],{"class":248}," kmdalert-0.2-77c0d6b4d49f.tar.gz\n",[239,2437,2438,2440],{"class":241,"line":260},[239,2439,255],{"class":254},[239,2441,2442],{"class":248}," kmdalert-77c0d6b4d49f\n",[239,2444,2445],{"class":241,"line":448},[239,2446,2447],{"class":520},"# Préparation de la compilation\n",[239,2449,2450,2452],{"class":241,"line":476},[239,2451,245],{"class":244},[239,2453,886],{"class":248},[239,2455,2456,2458],{"class":241,"line":498},[239,2457,255],{"class":254},[239,2459,886],{"class":248},[239,2461,2462],{"class":241,"line":503},[239,2463,2464],{"class":520},"# Comilation\n",[239,2466,2467,2469],{"class":241,"line":509},[239,2468,897],{"class":244},[239,2470,2471],{"class":248}," ..\u002Fmake\n",[239,2473,2474],{"class":241,"line":524},[239,2475,2476],{"class":520},"# Installation\n",[239,2478,2479,2482],{"class":241,"line":541},[239,2480,2481],{"class":244},"make",[239,2483,2484],{"class":248}," install\n",[11,2486,2487],{},"La compilation nécessite les librairies de développement KDE et Qt3,\nainsi que le compilateur GCC.",[97,2489,2491],{"id":2490},"licence","Licence",[11,2493,2494,2495],{},"La licence choisie est la ",[37,2496,2499],{"href":2497,"rel":2498},"http:\u002F\u002Fwww.gnu.org\u002Flicenses\u002Fgpl-2.0.txt",[113],"GNU GENERAL PUBLIC LICENSE",[97,2501,2503],{"id":2502},"téléchargement","Téléchargement",[333,2505,2506,2514,2522],{},[106,2507,2508,2509,45],{},"Vous pouvez télécharger une archive déjà construite de l'application\nsur ",[37,2510,2513],{"href":2511,"rel":2512},"http:\u002F\u002Fkde-apps.org\u002Fcontent\u002Fshow.php\u002FKMDAlert?content=73373",[113],"KDE-Apps.org",[106,2515,2516,2517,45],{},"Le dépôt officiel pour télécharger les sources et participer :\n",[37,2518,2521],{"href":2519,"rel":2520},"https:\u002F\u002Fgogs.shadoware.org\u002Fphoenix\u002Fkmdalert?pk_campaign=shadoware",[113],"https:\u002F\u002Fgogs.shadoware.org\u002Fphoenix\u002Fkmdalert",[106,2523,2524],{},"Vous pouvez également télécharger la version attachée au billet.",[97,2526,2528],{"id":2527},"système-de-suivi","Système de suivi",[11,2530,2531],{},"Il n'y a actuellement plus de système de suivi pour ce logiciel. En cas\nde problème, vous pouvez laisser un message dans les commentaires ou\nm'envoyer un mail.",[1709,2533,2534],{},"html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":42,"searchDepth":135,"depth":135,"links":2536},[2537,2538,2539,2540,2541,2542],{"id":2299,"depth":135,"text":2300},{"id":2335,"depth":135,"text":2336},{"id":2407,"depth":135,"text":2408},{"id":2490,"depth":135,"text":2491},{"id":2502,"depth":135,"text":2503},{"id":2527,"depth":135,"text":2528},"kmdalert","2011-08-14",{"type":8,"value":2546},[2547,2549,2553,2557,2565,2567],[97,2548,2300],{"id":2299},[11,2550,2303,2551,2308],{},[37,2552,2307],{"href":2306},[11,2554,2311,2555,2315],{},[209,2556,2314],{},[333,2558,2559,2561,2563],{},[106,2560,2320],{},[106,2562,2323],{},[106,2564,2326],{},[11,2566,2329],{},[11,2568,2332],{},{},"\u002Fpost\u002Fkmdalert-0.2",{"title":2294,"description":42},"kmdalert-0.2","posts\u002FKMDAlert\u002F2011-08-14-kmdalert-0.2",[180,1754,2543,2575],"raid","4FaKIyQl43RcZ_dgavc_Yj95PpItKkc48C5B55Yud_8",{"id":2578,"title":2579,"author":6,"body":2580,"category":1724,"categorySlug":1725,"date":5698,"description":42,"excerpt":5699,"extension":170,"location":171,"meta":5772,"navigation":173,"path":5773,"published":173,"seo":5774,"slug":5775,"stem":5776,"tags":5777,"timeToRead":725,"__hash__":5779},"posts\u002Fposts\u002FProgrammation\u002F2011-01-25-qt-performance-de-l-utilisation-de-qsharedpointer.md","C++\u002FQt - Performance de l'utilisation de QSharedPointer",{"type":8,"value":2581,"toc":5691},[2582,2584,2594,2614,2623,2687,2691,2695,2699,2712,2723,2729,2733,2755,2783,2882,2889,2899,2905,2950,2956,2980,2991,3005,3035,3054,3110,3123,3129,3138,3203,3213,3219,3265,3287,3293,3431,3450,3458,3475,3478,3627,3650,3657,3730,3734,3737,3740,4029,4032,4310,4313,4319,4322,4325,4448,4476,4480,4491,4511,4524,4528,4537,4545,4693,4708,4726,4819,4822,4825,4856,4860,4866,4880,4883,4887,4894,4897,4911,4914,4934,4937,4951,4955,4960,4969,4972,4982,5106,5176,5180,5183,5205,5209,5215,5279,5283,5290,5296,5337,5340,5397,5401,5404,5508,5514,5517,5520,5524,5531,5548,5688],[190,2583,2300],{"id":2299},[11,2585,2586,2589,2590,2593],{},[209,2587,2588],{},"Qt"," est un framework orienté objet écrit en C++ et permettant de faire\ndes interfaces graphiques. Ce framework est utilisé par le projet ",[209,2591,2592],{},"KDE","\ndepuis ses débuts pour en faire un environnement de bureau très complet.",[11,2595,2596,2598,2599,2602,2607,2608,2610,2611,2613],{},[209,2597,2588],{}," fournit un ensemble de pointeur ",[209,2600,2601],{},"intelligent",[34,2603,2604],{},[37,2605,44],{"href":39,"ariaDescribedBy":2606,"dataFootnoteRef":42,"id":43},[41]," permettant\nde gérer plus facilement la mémoire. Le but est alors de ne plus avoir à\nsupprimer des objets. La suppression se fera soit par un pointeur\n",[209,2609,2601],{}," soit par le système de hiérarchie d'objet existant en ",[209,2612,2588],{},"\n(l'objet père qui supprime l'ensemble des objets fils qui lui sont\nrattachés).",[11,2615,2616,2618,2619,2622],{},[209,2617,2588],{}," propose l'ensemble des pointeurs ",[209,2620,2621],{},"intelligents"," suivants:",[333,2624,2625,2648,2662,2670],{},[106,2626,2627,2632,2633,2638,2639,2642,2643,45],{},[37,2628,2631],{"href":2629,"rel":2630},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqshareddatapointer.html",[113],"QSharedDataPointer"," \u002F ",[37,2634,2637],{"href":2635,"rel":2636},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqshareddata.html",[113],"QSharedData"," : ces deux classes\nutilisées ensemble permettent d'écrire un objet avec partage\nimplicite. Cela signifie que l'objet fonctionnera comme la classe\n",[209,2640,2641],{},"QString",". Tant que l'objet est copié, passé en paramètre, ....\nl'objet n'est pas dupliqué (tous les objets pointes vers le même\nespace mémoire). Au moment où l'objet est modifié, l'objet est\ndupliqué. C'est ce qu'on appelle le COW",[34,2644,2645],{},[37,2646,76],{"href":73,"ariaDescribedBy":2647,"dataFootnoteRef":42,"id":75},[41],[106,2649,2650,2632,2655,2658,2659,2661],{},[37,2651,2654],{"href":2652,"rel":2653},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqexplicitlyshareddatapointer.html",[113],"QExplictlySharedDataPointer",[37,2656,2637],{"href":2635,"rel":2657},[113]," :\nQExplicitlySharedDataPointer est une variante de QSharedDataPointer.\nCe pointeur ",[209,2660,2601],{},", comme son nom l'indique, est détaché\nuniquement lorsque la méthode detach() est appelée explicitement.\nCette classe permet de faire des objets qui fonctionnent comme des\npointeurs mais qui sont utilisés sans la notion de pointeur (le *).\nLa suppression des données partagées se fait donc quand tous les\nobjets ne sont plus utilisés.",[106,2663,2664,2669],{},[37,2665,2668],{"href":2666,"rel":2667},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqscopedpointer.html",[113],"QScopedPointer"," : Ce pointeur est le plus simple. Il permet de\ndéclarer un pointeur sur le tas et s'occupe de la destruction de\nl'objet, lorsque le programme sort de la portée du bloc. Cela permet\nde ne plus se soucier de la libération du pointeur dans les cas\nd'erreur (exception, retour avant la fin de la fonction car le\nfichier n'a pu être ouvert, ...).",[106,2671,2672,2677,2678,2686],{},[37,2673,2676],{"href":2674,"rel":2675},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqsharedpointer.html",[113],"QSharedPointer"," : Le pointeur dont on parlera dans la suite de ce\nbillet. Il permet de partager non plus des données (comme le fait\nQSharedData) mais de partager un pointeur",[34,2679,2680],{},[37,2681,2685],{"href":2682,"ariaDescribedBy":2683,"dataFootnoteRef":42,"id":2684},"#user-content-fn-3",[41],"user-content-fnref-3","3",". Nous allons voir\ndans la suite du billet, comment simplement utiliser ce pointeur, et\nles performances de ce pointeur par rapport à un pointeur standard.",[190,2688,2690],{"id":2689},"sommaire","Sommaire",[190,2692,2694],{"id":2693},"utilisation-de-qsharedpointer","Utilisation de QSharedPointer",[2184,2696,2698],{"id":2697},"a-quoi-sert-il","A quoi sert-il ?",[11,2700,2701,2702,2704,2705,2707,2708,2711],{},"L'objet ",[236,2703,2676],{}," fait partie des pointeurs ",[209,2706,2621],{},". Ces\npointeurs permettent de gérer automatiquement la libération de la\nmémoire (plus besoin de faire ",[236,2709,2710],{},"delete ptr;"," quand le pointeur n'est plus\nutilisé) tout en restant utilisable comme un pointeur normal.",[11,2713,2714,2716,2717,2719,2720,2722],{},[236,2715,2676],{}," fonctionne par comptage de référence. Après la\ndéclaration, à chaque affectation, on augmente le compteur de référence,\nlorsqu'on quitte la portée du bloc, on décrémente le compteur de\nréférence. ",[236,2718,2676],{}," détruit donc automatiquement le pointeur\nquand il n'existe plus aucune référence vers ce pointeur.\n",[236,2721,2676],{}," vient donc comme une encapsulation de notre pointeur.",[11,2724,2725],{},[49,2726],{"alt":2727,"src":2728},"QSharedPointer vers la même adresse","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer1.png",[2184,2730,2732],{"id":2731},"comment-lutiliser","Comment l'utiliser ?",[11,2734,2735,2736,2739,2740,2743,2744,2747,2748,2751,2752,2754],{},"La déclaration d'un pointeur en C, se fait en écrivant ",[236,2737,2738],{},"MyObject*",". La\nsyntaxe en utilisant un QSharedPointer se fait en écrivant\n",[236,2741,2742],{},"QSharedPointer\u003CMyObject>",". Par la suite dans le programme,\nl'utilisation du pointeur ",[236,2745,2746],{},"QSharedObject"," se fera de la même manière\nqu'un pointeur C. (Avec l'opérateur ",[236,2749,2750],{},"->"," pour appeler un membre, une\nméthode, ...) . Appelons dans la suite pointeur C, les pointeurs\nstandards et ",[236,2753,2676],{},", le pointeur intelligent.",[11,2756,2757,2758,2760,2761,2764,2765,2767,2768,2770,2771,2774,2775,45],{},"Afin d'éviter d'avoir un pointeur normal pouvant être supprimé à tout\nmoment dans l'application, lors de l'utilisation de ",[236,2759,2676],{},", il\nne faut utiliser le pointeur C résultant du ",[236,2762,2763],{},"new"," que pour la création\ndu ",[236,2766,2676],{},". On peut donc directement créer le ",[236,2769,2676],{},"\nen utilisant le constructeur ",[236,2772,2773],{},"QSharedPointer ( T * ptr )"," qui prend en\nparamètre le pointeur C. C'est entre ces parenthèses que nous allons\ncréer le pointeur C",[34,2776,2777],{},[37,2778,2782],{"href":2779,"ariaDescribedBy":2780,"dataFootnoteRef":42,"id":2781},"#user-content-fn-4",[41],"user-content-fnref-4","4",[230,2784,2786],{"className":384,"code":2785,"language":386,"meta":42,"style":42},"{\n    \u002F\u002F Création du pointeur intelligent à partir d'un pointeur normal.\n    QSharedPointer\u003CMyObject> ptr(new MyObject());\n\n    \u002F\u002F Utilisation du pointeur intelligent comme un pointeur normal.\n    if (ptr)\n    {\n        ptr->setMembre(maValeur);\n    }\n\n    \u002F\u002F Appel d'une méthode utilisant ce pointeur\n    maMethode(ptr);\n}\n",[236,2787,2788,2793,2798,2823,2827,2832,2839,2844,2857,2861,2865,2870,2878],{"__ignoreMap":42},[239,2789,2790],{"class":241,"line":181},[239,2791,2792],{"class":400},"{\n",[239,2794,2795],{"class":241,"line":135},[239,2796,2797],{"class":520},"    \u002F\u002F Création du pointeur intelligent à partir d'un pointeur normal.\n",[239,2799,2800,2803,2805,2808,2811,2814,2816,2818,2821],{"class":241,"line":260},[239,2801,2802],{"class":400},"    QSharedPointer",[239,2804,699],{"class":393},[239,2806,2807],{"class":400},"MyObject",[239,2809,2810],{"class":393},">",[239,2812,2813],{"class":244}," ptr",[239,2815,401],{"class":400},[239,2817,2763],{"class":393},[239,2819,2820],{"class":244}," MyObject",[239,2822,771],{"class":400},[239,2824,2825],{"class":241,"line":448},[239,2826,445],{"emptyLinePlaceholder":173},[239,2828,2829],{"class":241,"line":476},[239,2830,2831],{"class":520},"    \u002F\u002F Utilisation du pointeur intelligent comme un pointeur normal.\n",[239,2833,2834,2836],{"class":241,"line":498},[239,2835,660],{"class":393},[239,2837,2838],{"class":400}," (ptr)\n",[239,2840,2841],{"class":241,"line":503},[239,2842,2843],{"class":400},"    {\n",[239,2845,2846,2849,2851,2854],{"class":241,"line":509},[239,2847,2848],{"class":410},"        ptr",[239,2850,2750],{"class":400},[239,2852,2853],{"class":244},"setMembre",[239,2855,2856],{"class":400},"(maValeur);\n",[239,2858,2859],{"class":241,"line":524},[239,2860,823],{"class":400},[239,2862,2863],{"class":241,"line":541},[239,2864,445],{"emptyLinePlaceholder":173},[239,2866,2867],{"class":241,"line":564},[239,2868,2869],{"class":520},"    \u002F\u002F Appel d'une méthode utilisant ce pointeur\n",[239,2871,2872,2875],{"class":241,"line":569},[239,2873,2874],{"class":244},"    maMethode",[239,2876,2877],{"class":400},"(ptr);\n",[239,2879,2880],{"class":241,"line":585},[239,2881,1580],{"class":400},[11,2883,2884,2885,2888],{},"Lorsque l'on quitte le bloc, si le comptage de référence tombe à 0, on\nsupprime le pointeur. A l'intérieur de ",[236,2886,2887],{},"maMethode()"," le nombre de\nréférence sera passé à 2. Si la méthode utilise le pointeur mais ne\nl'assigne nul part, le nombre de référence devrait être retombé à 1 et\ndonc ici sera décrémenté à 0.",[11,2890,2891,2892,2894,2895,2898],{},"Si par contre, ",[236,2893,2887],{}," fait des opérations d'assignation de ",[236,2896,2897],{},"ptr","\net conserve une copie, le comptage ne tombera pas à 0 tant que l'objet\nrestera utilisé (assigné) ailleurs.",[11,2900,2901,2902,2904],{},"Regardons un exemple de ",[236,2903,2887],{}," :",[230,2906,2908],{"className":384,"code":2907,"language":386,"meta":42,"style":42},"void maMethode(QSharedPointer\u003CMyObject> ptr)\n{\n    ptr->setMembre2(maValeur);\n",[236,2909,2910,2934,2938],{"__ignoreMap":42},[239,2911,2912,2915,2918,2920,2922,2924,2926,2929,2931],{"class":241,"line":181},[239,2913,2914],{"class":393},"void",[239,2916,2917],{"class":244}," maMethode",[239,2919,401],{"class":400},[239,2921,2676],{"class":410},[239,2923,699],{"class":400},[239,2925,2807],{"class":410},[239,2927,2928],{"class":400},"> ",[239,2930,2897],{"class":417},[239,2932,2933],{"class":400},")\n",[239,2935,2936],{"class":241,"line":135},[239,2937,2792],{"class":400},[239,2939,2940,2943,2945,2948],{"class":241,"line":260},[239,2941,2942],{"class":410},"    ptr",[239,2944,2750],{"class":400},[239,2946,2947],{"class":244},"setMembre2",[239,2949,2856],{"class":400},[11,2951,2952,2953,2955],{},"Au début du bloc, ici le comptage de référence est à 2 et sera\ndécrémenté à la sortie de la méthode. On peut modifier les membres de\n",[236,2954,2897],{},", et dans ce cas pas de changement du comptage de référence.",[230,2957,2959],{"className":384,"code":2958,"language":386,"meta":42,"style":42},"    this->monPtr = ptr;\n}\n",[236,2960,2961,2976],{"__ignoreMap":42},[239,2962,2963,2966,2968,2971,2973],{"class":241,"line":181},[239,2964,2965],{"class":410},"    this",[239,2967,2750],{"class":400},[239,2969,2970],{"class":606},"monPtr",[239,2972,1986],{"class":393},[239,2974,2975],{"class":400}," ptr;\n",[239,2977,2978],{"class":241,"line":135},[239,2979,1580],{"class":400},[11,2981,2982,2983,2986,2987,2990],{},"Au contraire, on peut également l'assigner à un autre objet. Dans ce cas\nle comptage de référence de cet objet passera à 3. A la sortie de la\nméthode il sera décrémenté et passera alors à 2. L'objet ne sera pas\nsupprimé tant qu'on ne fera pas un ",[236,2984,2985],{},"this->monPtr.clear()"," ou que ",[236,2988,2989],{},"this","\nne sera pas détruit.",[11,2992,2993,2994,2996,2997,3000,3001,3004],{},"Si on veut garder une référence d'un pointeur mais qu'on ne souhaite pas\nque celle-ci incrémente le nombre de référence du ",[236,2995,2676],{},", il\nest possible de créer un pointeur ",[209,2998,2999],{},"faible",". Ce pointeur passe par\nl'objet ",[236,3002,3003],{},"QWeakPointer",". Pour obtenir ce type de pointeur, il suffit de\nfaire :",[230,3006,3008],{"className":384,"code":3007,"language":386,"meta":42,"style":42},"QWeakPointer\u003CMyObject> ptrW = ptr->toWeakRef ();\n",[236,3009,3010],{"__ignoreMap":42},[239,3011,3012,3014,3016,3018,3020,3023,3025,3027,3029,3032],{"class":241,"line":181},[239,3013,3003],{"class":400},[239,3015,699],{"class":393},[239,3017,2807],{"class":400},[239,3019,2810],{"class":393},[239,3021,3022],{"class":400}," ptrW ",[239,3024,547],{"class":393},[239,3026,2813],{"class":410},[239,3028,2750],{"class":400},[239,3030,3031],{"class":244},"toWeakRef",[239,3033,3034],{"class":400}," ();\n",[11,3036,3037,3040,3041,3043,3044,3047,3048,3050,3051,45],{},[236,3038,3039],{},"ptrW"," n'incrémente donc pas le comptage de référence, cela signifie\ndonc que le pointeur peut être détruit même si un objet ",[236,3042,3003],{},"\nexiste. Il sera alors possible de faire un ",[236,3045,3046],{},"ptrW.isNull()"," pour savoir\nsi le pointeur est toujours valide. Si l'utilisateur a également besoin\nd'avoir accès à un membre de l'objet, il pourra le transformer en\n",[236,3049,2676],{}," avant de l'utiliser sauf si le pointeur est ",[236,3052,3053],{},"null",[230,3055,3057],{"className":384,"code":3056,"language":386,"meta":42,"style":42},"QSharedPointer\u003CMyObject> ptr2 = ptrW->toStrongRef ();\nif (ptr)\n{\n    ptr->maMethodePtr();\n}\n",[236,3058,3059,3084,3091,3095,3106],{"__ignoreMap":42},[239,3060,3061,3063,3065,3067,3069,3072,3074,3077,3079,3082],{"class":241,"line":181},[239,3062,2676],{"class":400},[239,3064,699],{"class":393},[239,3066,2807],{"class":400},[239,3068,2810],{"class":393},[239,3070,3071],{"class":400}," ptr2 ",[239,3073,547],{"class":393},[239,3075,3076],{"class":410}," ptrW",[239,3078,2750],{"class":400},[239,3080,3081],{"class":244},"toStrongRef",[239,3083,3034],{"class":400},[239,3085,3086,3089],{"class":241,"line":135},[239,3087,3088],{"class":393},"if",[239,3090,2838],{"class":400},[239,3092,3093],{"class":241,"line":260},[239,3094,2792],{"class":400},[239,3096,3097,3099,3101,3104],{"class":241,"line":448},[239,3098,2942],{"class":410},[239,3100,2750],{"class":400},[239,3102,3103],{"class":244},"maMethodePtr",[239,3105,710],{"class":400},[239,3107,3108],{"class":241,"line":476},[239,3109,1580],{"class":400},[11,3111,3112,3113,3116,3117,3119,3120,3122],{},"Il faut tester que ",[236,3114,3115],{},"ptr2"," est encore valide, car tant que la\ntransformation du pointeur ",[209,3118,2999],{}," vers le ",[236,3121,2676],{}," n'a pas\nencore été fait, il est possible que le nombre de référence vers l'objet\nsoit tombé à 0 et qu'il ait été supprimé.",[2184,3124,3126,3127],{"id":3125},"comment-utiliser-this","Comment utiliser ",[236,3128,2989],{},[11,3130,3131,3132,3134,3135,3137],{},"Un des points peu pratique de l'utilisation de ",[236,3133,2676],{}," est que\nle comptage de référence ne fonctionne pas si plusieurs ",[236,3136,2676],{},"\npointent vers le même objet mais ont tous été créés à partir du pointeur\nC. Prenons par exemple, le cas suivant :",[230,3139,3141],{"className":384,"code":3140,"language":386,"meta":42,"style":42},"MyObject * ptr = new MyObject();\n\nQSharedPointer\u003CMyObject> ptr1 = QSharedPointer(ptr);\nQSharedPointer\u003CMyObject> ptr2 = QSharedPointer(ptr);\n",[236,3142,3143,3161,3165,3185],{"__ignoreMap":42},[239,3144,3145,3148,3150,3153,3155,3157,3159],{"class":241,"line":181},[239,3146,3147],{"class":400},"MyObject ",[239,3149,760],{"class":393},[239,3151,3152],{"class":400}," ptr ",[239,3154,547],{"class":393},[239,3156,2039],{"class":393},[239,3158,2820],{"class":244},[239,3160,710],{"class":400},[239,3162,3163],{"class":241,"line":135},[239,3164,445],{"emptyLinePlaceholder":173},[239,3166,3167,3169,3171,3173,3175,3178,3180,3183],{"class":241,"line":260},[239,3168,2676],{"class":400},[239,3170,699],{"class":393},[239,3172,2807],{"class":400},[239,3174,2810],{"class":393},[239,3176,3177],{"class":400}," ptr1 ",[239,3179,547],{"class":393},[239,3181,3182],{"class":244}," QSharedPointer",[239,3184,2877],{"class":400},[239,3186,3187,3189,3191,3193,3195,3197,3199,3201],{"class":241,"line":448},[239,3188,2676],{"class":400},[239,3190,699],{"class":393},[239,3192,2807],{"class":400},[239,3194,2810],{"class":393},[239,3196,3071],{"class":400},[239,3198,547],{"class":393},[239,3200,3182],{"class":244},[239,3202,2877],{"class":400},[11,3204,3205,3206,3209,3210,3212],{},"Le problème d'écrire ces lignes ainsi, et que pour ",[236,3207,3208],{},"ptr1"," comme pour\n",[236,3211,3115],{},", l'objet n'est référencé qu'une fois. Ainsi le premier qui\ntombera à 0 détruira l'objet, alors que l'autre pourrait encore\nl'utiliser. Il faut donc écrire les choses comme suite :",[11,3214,3215],{},[49,3216],{"alt":3217,"src":3218},"Deux QSharedPointer créé vers la même adresse","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer2.png",[230,3220,3222],{"className":384,"code":3221,"language":386,"meta":42,"style":42},"QSharedPointer\u003CMyObject> ptr1 = QSharedPointer(new MyObject());\nQSharedPointer\u003CMyObject> ptr2 = ptr1;\n",[236,3223,3224,3248],{"__ignoreMap":42},[239,3225,3226,3228,3230,3232,3234,3236,3238,3240,3242,3244,3246],{"class":241,"line":181},[239,3227,2676],{"class":400},[239,3229,699],{"class":393},[239,3231,2807],{"class":400},[239,3233,2810],{"class":393},[239,3235,3177],{"class":400},[239,3237,547],{"class":393},[239,3239,3182],{"class":244},[239,3241,401],{"class":400},[239,3243,2763],{"class":393},[239,3245,2820],{"class":244},[239,3247,771],{"class":400},[239,3249,3250,3252,3254,3256,3258,3260,3262],{"class":241,"line":135},[239,3251,2676],{"class":400},[239,3253,699],{"class":393},[239,3255,2807],{"class":400},[239,3257,2810],{"class":393},[239,3259,3071],{"class":400},[239,3261,547],{"class":393},[239,3263,3264],{"class":400}," ptr1;\n",[11,3266,3267,3268,2367,3270,3272,3273,3275,3276,3278,3279,3281,3282,3284,3285,45],{},"Ainsi ",[236,3269,3208],{},[236,3271,3115],{}," ont bien chacun connaissance de l'existence de\nl'autre. Cela contraint donc à remplacer toutes les déclarations du type\n",[236,3274,2738],{}," par ",[236,3277,2742],{},". Ceci est donc à faire dans\nles paramètres des méthodes, dans les membres, dans la déclaration des\nvariables locales, ... . On ne peut donc plus utiliser le pointeur C\n",[236,3280,2738],{}," directement, mais seulement au travers de ",[236,3283,2676],{},"\nou de ",[236,3286,3003],{},[11,3288,3289,3290,3292],{},"Cela commence à poser problème lors de l'utilisation de ",[236,3291,2989],{}," dans un\nobjet. Imaginons une méthode d'un objet mettant à jour des membres fils\navec en paramètre le père. Nous aurions alors tendance à écrire ceci :",[230,3294,3296],{"className":384,"code":3295,"language":386,"meta":42,"style":42},"void Object2::setParent(QSharedPointer\u003CMyObject> parent)\n{\n    ...\n}\n\n....\n\nvoid MyObject::setMember(Object2 * obj)\n{\n    _membre = obj;\n    if (obj)\n    {\n        obj->setParent(QSharedPointer\u003CMyObject>(this));\n    }\n}\n",[236,3297,3298,3325,3329,3334,3338,3342,3347,3351,3374,3378,3388,3395,3399,3423,3427],{"__ignoreMap":42},[239,3299,3300,3302,3305,3307,3310,3312,3314,3316,3318,3320,3323],{"class":241,"line":181},[239,3301,2914],{"class":393},[239,3303,3304],{"class":410}," Object2",[239,3306,1168],{"class":400},[239,3308,3309],{"class":244},"setParent",[239,3311,401],{"class":400},[239,3313,2676],{"class":410},[239,3315,699],{"class":400},[239,3317,2807],{"class":410},[239,3319,2928],{"class":400},[239,3321,3322],{"class":417},"parent",[239,3324,2933],{"class":400},[239,3326,3327],{"class":241,"line":135},[239,3328,2792],{"class":400},[239,3330,3331],{"class":241,"line":260},[239,3332,3333],{"class":400},"    ...\n",[239,3335,3336],{"class":241,"line":448},[239,3337,1580],{"class":400},[239,3339,3340],{"class":241,"line":476},[239,3341,445],{"emptyLinePlaceholder":173},[239,3343,3344],{"class":241,"line":498},[239,3345,3346],{"class":400},"....\n",[239,3348,3349],{"class":241,"line":503},[239,3350,445],{"emptyLinePlaceholder":173},[239,3352,3353,3355,3357,3359,3362,3364,3367,3369,3372],{"class":241,"line":509},[239,3354,2914],{"class":393},[239,3356,2820],{"class":410},[239,3358,1168],{"class":400},[239,3360,3361],{"class":244},"setMember",[239,3363,401],{"class":400},[239,3365,3366],{"class":410},"Object2",[239,3368,787],{"class":393},[239,3370,3371],{"class":417}," obj",[239,3373,2933],{"class":400},[239,3375,3376],{"class":241,"line":524},[239,3377,2792],{"class":400},[239,3379,3380,3383,3385],{"class":241,"line":541},[239,3381,3382],{"class":400},"    _membre ",[239,3384,547],{"class":393},[239,3386,3387],{"class":400}," obj;\n",[239,3389,3390,3392],{"class":241,"line":564},[239,3391,660],{"class":393},[239,3393,3394],{"class":400}," (obj)\n",[239,3396,3397],{"class":241,"line":569},[239,3398,2843],{"class":400},[239,3400,3401,3404,3406,3408,3410,3412,3414,3416,3419,3421],{"class":241,"line":585},[239,3402,3403],{"class":410},"        obj",[239,3405,2750],{"class":400},[239,3407,3309],{"class":244},[239,3409,401],{"class":400},[239,3411,2676],{"class":244},[239,3413,699],{"class":400},[239,3415,2807],{"class":410},[239,3417,3418],{"class":400},">(",[239,3420,2989],{"class":410},[239,3422,473],{"class":400},[239,3424,3425],{"class":241,"line":590},[239,3426,823],{"class":400},[239,3428,3429],{"class":241,"line":652},[239,3430,1580],{"class":400},[11,3432,3433,3434,3436,3437,2387,3445,3447,3448,45],{},"Ceci ne marchera pas car on créerait un nouvel objet ",[236,3435,2676],{},"\ncommençant son comptage de référence à 1, alors que nous en avons déjà\nau moins un autre pointant vers notre instance",[34,3438,3439],{},[37,3440,3444],{"href":3441,"ariaDescribedBy":3442,"dataFootnoteRef":42,"id":3443},"#user-content-fn-5",[41],"user-content-fnref-5","5",[236,3446,2807],{},"\npourrait alors être détruit alors qu'il est encore utilisé par\n",[236,3449,3366],{},[11,3451,3452,3453,3455,3457],{},"Pour éviter cela, il faut alors passer par un pointeur ",[209,3454,2601],{},[236,3456,2989],{},". Pour cela nous allons utiliser deux choses :",[333,3459,3460,3472],{},[106,3461,3462,3463,3466,3467,3469,3471],{},"Un membre nommé ",[236,3464,3465],{},"_this"," de type pointeur ",[209,3468,2601],{},[236,3470,3003],{},", contenant une référence à l'objet lui même. (Nous\nn'utilisons pas un QSharedPointer, pour éviter une référence\ncirculaire, voir le paragraphe suivant).",[106,3473,3474],{},"Une méthode statique utilisée pour la création (nous n'allons plus\nutiliser le constructeur, car à ce moment, il n'existe pas encore de\nQSharedPointer pointant vers notre objet).",[11,3476,3477],{},"Voici un exemple de comment écrire le constructeur maison :",[230,3479,3481],{"className":384,"code":3480,"language":386,"meta":42,"style":42},"class MyObject\n{\npublic:\n    static QSharedPointer\u003CMyObject> create(QString parametre)\n    {\n        QSharedPointer\u003CMyObject> ptr(new MyObject(parametre);\n        ptr->_this = ptr.toWeakRef();\n        return ptr;\n    }\nprivate:\n    MyObject(QString parametre)\n    {\n        ...\n    }\n\n    QWeakPointer\u003CMyObject> _this;\n};\n",[236,3482,3483,3491,3495,3500,3525,3529,3551,3569,3575,3579,3584,3592,3596,3601,3605,3609,3623],{"__ignoreMap":42},[239,3484,3485,3488],{"class":241,"line":181},[239,3486,3487],{"class":393},"class",[239,3489,3490],{"class":410}," MyObject\n",[239,3492,3493],{"class":241,"line":135},[239,3494,2792],{"class":400},[239,3496,3497],{"class":241,"line":260},[239,3498,3499],{"class":393},"public:\n",[239,3501,3502,3505,3507,3509,3511,3513,3516,3518,3520,3523],{"class":241,"line":448},[239,3503,3504],{"class":393},"    static",[239,3506,3182],{"class":410},[239,3508,699],{"class":400},[239,3510,2807],{"class":410},[239,3512,2928],{"class":400},[239,3514,3515],{"class":244},"create",[239,3517,401],{"class":400},[239,3519,2641],{"class":410},[239,3521,3522],{"class":417}," parametre",[239,3524,2933],{"class":400},[239,3526,3527],{"class":241,"line":476},[239,3528,2843],{"class":400},[239,3530,3531,3534,3536,3538,3540,3542,3544,3546,3548],{"class":241,"line":498},[239,3532,3533],{"class":400},"        QSharedPointer",[239,3535,699],{"class":393},[239,3537,2807],{"class":400},[239,3539,2810],{"class":393},[239,3541,2813],{"class":244},[239,3543,401],{"class":400},[239,3545,2763],{"class":393},[239,3547,2820],{"class":244},[239,3549,3550],{"class":400},"(parametre);\n",[239,3552,3553,3555,3557,3559,3561,3563,3565,3567],{"class":241,"line":503},[239,3554,2848],{"class":410},[239,3556,2750],{"class":400},[239,3558,3465],{"class":606},[239,3560,1986],{"class":393},[239,3562,2813],{"class":410},[239,3564,45],{"class":400},[239,3566,3031],{"class":244},[239,3568,710],{"class":400},[239,3570,3571,3573],{"class":241,"line":509},[239,3572,690],{"class":393},[239,3574,2975],{"class":400},[239,3576,3577],{"class":241,"line":524},[239,3578,823],{"class":400},[239,3580,3581],{"class":241,"line":541},[239,3582,3583],{"class":400},"private:\n",[239,3585,3586,3589],{"class":241,"line":564},[239,3587,3588],{"class":244},"    MyObject",[239,3590,3591],{"class":400},"(QString parametre)\n",[239,3593,3594],{"class":241,"line":569},[239,3595,2843],{"class":400},[239,3597,3598],{"class":241,"line":585},[239,3599,3600],{"class":400},"        ...\n",[239,3602,3603],{"class":241,"line":590},[239,3604,823],{"class":400},[239,3606,3607],{"class":241,"line":652},[239,3608,445],{"emptyLinePlaceholder":173},[239,3610,3611,3614,3616,3618,3620],{"class":241,"line":657},[239,3612,3613],{"class":400},"    QWeakPointer",[239,3615,699],{"class":393},[239,3617,2807],{"class":400},[239,3619,2810],{"class":393},[239,3621,3622],{"class":400}," _this;\n",[239,3624,3625],{"class":241,"line":687},[239,3626,1073],{"class":400},[11,3628,3629,3630,3632,3633,3635,3636,3638,3639,3641,3642,3644,3645,3647,3648,45],{},"Le constructeur devient alors privé (ou protégé si on a besoin de la\nnotion d'héritage) afin d'obliger l'utilisateur de la classe à utiliser\nnotre méthode de création. Dans notre nouvelle méthode de création\n",[236,3631,3515],{},", qui est une méthode statique, nous allons créer le pointeur et\ninitialiser le ",[236,3634,3003],{}," de notre objet avec le pointeur\n",[209,3637,2601],{}," que nous venons de créer. Nous retournons un\n",[236,3640,2676],{},". La méthode ",[236,3643,3515],{}," devient alors notre nouveau\nconstructeur, mais créant des instances d'objets de type\n",[236,3646,2742],{}," et non plus des instances d'objet\n",[236,3649,2738],{},[11,3651,3652,3653,3656],{},"Notre méthode ",[236,3654,3655],{},"setMember()"," peut alors être ré-écrite :",[230,3658,3660],{"className":384,"code":3659,"language":386,"meta":42,"style":42},"void MyObject::setMember(Object2 * obj)\n{\n    _membre = obj;\n    if (obj)\n    {\n        obj->setParent(_this.toStrongRef());\n    }\n}\n",[236,3661,3662,3682,3686,3694,3700,3704,3722,3726],{"__ignoreMap":42},[239,3663,3664,3666,3668,3670,3672,3674,3676,3678,3680],{"class":241,"line":181},[239,3665,2914],{"class":393},[239,3667,2820],{"class":410},[239,3669,1168],{"class":400},[239,3671,3361],{"class":244},[239,3673,401],{"class":400},[239,3675,3366],{"class":410},[239,3677,787],{"class":393},[239,3679,3371],{"class":417},[239,3681,2933],{"class":400},[239,3683,3684],{"class":241,"line":135},[239,3685,2792],{"class":400},[239,3687,3688,3690,3692],{"class":241,"line":260},[239,3689,3382],{"class":400},[239,3691,547],{"class":393},[239,3693,3387],{"class":400},[239,3695,3696,3698],{"class":241,"line":448},[239,3697,660],{"class":393},[239,3699,3394],{"class":400},[239,3701,3702],{"class":241,"line":476},[239,3703,2843],{"class":400},[239,3705,3706,3708,3710,3712,3714,3716,3718,3720],{"class":241,"line":498},[239,3707,3403],{"class":410},[239,3709,2750],{"class":400},[239,3711,3309],{"class":244},[239,3713,401],{"class":400},[239,3715,3465],{"class":410},[239,3717,45],{"class":400},[239,3719,3081],{"class":244},[239,3721,771],{"class":400},[239,3723,3724],{"class":241,"line":503},[239,3725,823],{"class":400},[239,3727,3728],{"class":241,"line":509},[239,3729,1580],{"class":400},[2184,3731,3733],{"id":3732},"comment-éviter-les-références-circulaires","Comment éviter les références circulaires",[11,3735,3736],{},"Le principe d'une référence circulaire est qu'un objet A référence\nl'objet B et l'objet B référence l'objet A.",[11,3738,3739],{},"Voici par exemple, un cas de référence circulaire :",[230,3741,3743],{"className":384,"code":3742,"language":386,"meta":42,"style":42},"class A\n{\npublic:\n    static create()\n    {\n        QSharedPointer\u003CA> ptr(new A());\n        return ptr;\n    }\n    ~A()\n    {\n    }\nprivate:\n    A()\n    {\n        b = B::create();\n        b->setA(_this);\n    }\n    QSharedPointer\u003CB> b;\n    QWeakPointer\u003CA> _this;\n};\n\nclass B\n{\npublic:\n    static QSharedPointer\u003CB> create()\n    {\n        QSharedPointer\u003CB> ptr(new B());\n        return ptr;\n    }\n    void setA(QSharedPointer\u003CA> b);\n    QSharedPointer\u003CA> getA();\nprivate:\n    QSharedPointer\u003CA>  a;\n};\n",[236,3744,3745,3752,3756,3760,3770,3774,3796,3802,3806,3813,3817,3821,3825,3832,3836,3850,3863,3867,3881,3893,3897,3901,3908,3912,3916,3932,3936,3957,3963,3967,3989,4005,4010,4024],{"__ignoreMap":42},[239,3746,3747,3749],{"class":241,"line":181},[239,3748,3487],{"class":393},[239,3750,3751],{"class":410}," A\n",[239,3753,3754],{"class":241,"line":135},[239,3755,2792],{"class":400},[239,3757,3758],{"class":241,"line":260},[239,3759,3499],{"class":393},[239,3761,3762,3764,3767],{"class":241,"line":448},[239,3763,3504],{"class":393},[239,3765,3766],{"class":244}," create",[239,3768,3769],{"class":400},"()\n",[239,3771,3772],{"class":241,"line":476},[239,3773,2843],{"class":400},[239,3775,3776,3778,3780,3783,3785,3787,3789,3791,3794],{"class":241,"line":498},[239,3777,3533],{"class":400},[239,3779,699],{"class":393},[239,3781,3782],{"class":400},"A",[239,3784,2810],{"class":393},[239,3786,2813],{"class":244},[239,3788,401],{"class":400},[239,3790,2763],{"class":393},[239,3792,3793],{"class":244}," A",[239,3795,771],{"class":400},[239,3797,3798,3800],{"class":241,"line":503},[239,3799,690],{"class":393},[239,3801,2975],{"class":400},[239,3803,3804],{"class":241,"line":509},[239,3805,823],{"class":400},[239,3807,3808,3811],{"class":241,"line":524},[239,3809,3810],{"class":244},"    ~A",[239,3812,3769],{"class":400},[239,3814,3815],{"class":241,"line":541},[239,3816,2843],{"class":400},[239,3818,3819],{"class":241,"line":564},[239,3820,823],{"class":400},[239,3822,3823],{"class":241,"line":569},[239,3824,3583],{"class":393},[239,3826,3827,3830],{"class":241,"line":585},[239,3828,3829],{"class":244},"    A",[239,3831,3769],{"class":400},[239,3833,3834],{"class":241,"line":590},[239,3835,2843],{"class":400},[239,3837,3838,3841,3843,3846,3848],{"class":241,"line":652},[239,3839,3840],{"class":400},"        b ",[239,3842,547],{"class":393},[239,3844,3845],{"class":400}," B::",[239,3847,3515],{"class":244},[239,3849,710],{"class":400},[239,3851,3852,3855,3857,3860],{"class":241,"line":657},[239,3853,3854],{"class":410},"        b",[239,3856,2750],{"class":400},[239,3858,3859],{"class":244},"setA",[239,3861,3862],{"class":400},"(_this);\n",[239,3864,3865],{"class":241,"line":687},[239,3866,823],{"class":400},[239,3868,3869,3871,3873,3876,3878],{"class":241,"line":713},[239,3870,2802],{"class":400},[239,3872,699],{"class":393},[239,3874,3875],{"class":400},"B",[239,3877,2810],{"class":393},[239,3879,3880],{"class":400}," b;\n",[239,3882,3883,3885,3887,3889,3891],{"class":241,"line":725},[239,3884,3613],{"class":400},[239,3886,699],{"class":393},[239,3888,3782],{"class":400},[239,3890,2810],{"class":393},[239,3892,3622],{"class":400},[239,3894,3895],{"class":241,"line":774},[239,3896,1073],{"class":400},[239,3898,3899],{"class":241,"line":812},[239,3900,445],{"emptyLinePlaceholder":173},[239,3902,3903,3905],{"class":241,"line":820},[239,3904,3487],{"class":393},[239,3906,3907],{"class":410}," B\n",[239,3909,3910],{"class":241,"line":1445},[239,3911,2792],{"class":400},[239,3913,3914],{"class":241,"line":1468},[239,3915,3499],{"class":393},[239,3917,3918,3920,3922,3924,3926,3928,3930],{"class":241,"line":1487},[239,3919,3504],{"class":393},[239,3921,3182],{"class":410},[239,3923,699],{"class":400},[239,3925,3875],{"class":410},[239,3927,2928],{"class":400},[239,3929,3515],{"class":244},[239,3931,3769],{"class":400},[239,3933,3934],{"class":241,"line":1495},[239,3935,2843],{"class":400},[239,3937,3938,3940,3942,3944,3946,3948,3950,3952,3955],{"class":241,"line":1534},[239,3939,3533],{"class":400},[239,3941,699],{"class":393},[239,3943,3875],{"class":400},[239,3945,2810],{"class":393},[239,3947,2813],{"class":244},[239,3949,401],{"class":400},[239,3951,2763],{"class":393},[239,3953,3954],{"class":244}," B",[239,3956,771],{"class":400},[239,3958,3959,3961],{"class":241,"line":1565},[239,3960,690],{"class":393},[239,3962,2975],{"class":400},[239,3964,3965],{"class":241,"line":1572},[239,3966,823],{"class":400},[239,3968,3969,3972,3975,3977,3979,3981,3983,3985,3987],{"class":241,"line":1577},[239,3970,3971],{"class":393},"    void",[239,3973,3974],{"class":244}," setA",[239,3976,401],{"class":400},[239,3978,2676],{"class":410},[239,3980,699],{"class":400},[239,3982,3782],{"class":410},[239,3984,2928],{"class":400},[239,3986,1175],{"class":417},[239,3988,1355],{"class":400},[239,3990,3992,3994,3996,3998,4000,4003],{"class":241,"line":3991},31,[239,3993,2802],{"class":410},[239,3995,699],{"class":400},[239,3997,3782],{"class":410},[239,3999,2928],{"class":400},[239,4001,4002],{"class":244},"getA",[239,4004,710],{"class":400},[239,4006,4008],{"class":241,"line":4007},32,[239,4009,3583],{"class":393},[239,4011,4013,4015,4017,4019,4021],{"class":241,"line":4012},33,[239,4014,2802],{"class":400},[239,4016,699],{"class":393},[239,4018,3782],{"class":400},[239,4020,2810],{"class":393},[239,4022,4023],{"class":400},"  a;\n",[239,4025,4027],{"class":241,"line":4026},34,[239,4028,1073],{"class":400},[11,4030,4031],{},"Cela peut-être aussi le cas, si par exemple une instance d'objet C\nréférence des instances d'objets fils C, qui possèdent eux-même un\npointeur vers l'objet C père.",[230,4033,4035],{"className":384,"code":4034,"language":386,"meta":42,"style":42},"class C\n{\npublic:\n    static QSharedPointer\u003CC> create()\n    {\n        QSharedPointer\u003CC> ptr(new C());\n        _this = ptr.toWeakPtr();\n        return ptr;\n    }\n\n    ~C()\n    {\n    }\n\n    void addChild(QSharedPointer\u003CC> c)\n    {\n        _childs.append(c);\n        c->setParent(_this);\n    }\n\n    void setParent(QSharedPointer\u003CC> c);\n    QSharedPointer\u003CC> getParent();\nprivate:\n    C()\n    {\n    }\n\n    QWeakPointer\u003CC> _this;\n    QSharedPointer\u003CC> _parent;\n    QList\u003C QSharedPointer\u003CC> > _childs;\n};\n",[236,4036,4037,4044,4048,4052,4069,4073,4094,4110,4116,4120,4124,4131,4135,4139,4143,4165,4169,4182,4193,4197,4201,4222,4237,4241,4248,4252,4256,4260,4272,4285,4306],{"__ignoreMap":42},[239,4038,4039,4041],{"class":241,"line":181},[239,4040,3487],{"class":393},[239,4042,4043],{"class":410}," C\n",[239,4045,4046],{"class":241,"line":135},[239,4047,2792],{"class":400},[239,4049,4050],{"class":241,"line":260},[239,4051,3499],{"class":393},[239,4053,4054,4056,4058,4060,4063,4065,4067],{"class":241,"line":448},[239,4055,3504],{"class":393},[239,4057,3182],{"class":410},[239,4059,699],{"class":400},[239,4061,4062],{"class":410},"C",[239,4064,2928],{"class":400},[239,4066,3515],{"class":244},[239,4068,3769],{"class":400},[239,4070,4071],{"class":241,"line":476},[239,4072,2843],{"class":400},[239,4074,4075,4077,4079,4081,4083,4085,4087,4089,4092],{"class":241,"line":498},[239,4076,3533],{"class":400},[239,4078,699],{"class":393},[239,4080,4062],{"class":400},[239,4082,2810],{"class":393},[239,4084,2813],{"class":244},[239,4086,401],{"class":400},[239,4088,2763],{"class":393},[239,4090,4091],{"class":244}," C",[239,4093,771],{"class":400},[239,4095,4096,4099,4101,4103,4105,4108],{"class":241,"line":503},[239,4097,4098],{"class":400},"        _this ",[239,4100,547],{"class":393},[239,4102,2813],{"class":410},[239,4104,45],{"class":400},[239,4106,4107],{"class":244},"toWeakPtr",[239,4109,710],{"class":400},[239,4111,4112,4114],{"class":241,"line":509},[239,4113,690],{"class":393},[239,4115,2975],{"class":400},[239,4117,4118],{"class":241,"line":524},[239,4119,823],{"class":400},[239,4121,4122],{"class":241,"line":541},[239,4123,445],{"emptyLinePlaceholder":173},[239,4125,4126,4129],{"class":241,"line":564},[239,4127,4128],{"class":244},"    ~C",[239,4130,3769],{"class":400},[239,4132,4133],{"class":241,"line":569},[239,4134,2843],{"class":400},[239,4136,4137],{"class":241,"line":585},[239,4138,823],{"class":400},[239,4140,4141],{"class":241,"line":590},[239,4142,445],{"emptyLinePlaceholder":173},[239,4144,4145,4147,4150,4152,4154,4156,4158,4160,4163],{"class":241,"line":652},[239,4146,3971],{"class":393},[239,4148,4149],{"class":244}," addChild",[239,4151,401],{"class":400},[239,4153,2676],{"class":410},[239,4155,699],{"class":400},[239,4157,4062],{"class":410},[239,4159,2928],{"class":400},[239,4161,4162],{"class":417},"c",[239,4164,2933],{"class":400},[239,4166,4167],{"class":241,"line":657},[239,4168,2843],{"class":400},[239,4170,4171,4174,4176,4179],{"class":241,"line":687},[239,4172,4173],{"class":410},"        _childs",[239,4175,45],{"class":400},[239,4177,4178],{"class":244},"append",[239,4180,4181],{"class":400},"(c);\n",[239,4183,4184,4187,4189,4191],{"class":241,"line":713},[239,4185,4186],{"class":410},"        c",[239,4188,2750],{"class":400},[239,4190,3309],{"class":244},[239,4192,3862],{"class":400},[239,4194,4195],{"class":241,"line":725},[239,4196,823],{"class":400},[239,4198,4199],{"class":241,"line":774},[239,4200,445],{"emptyLinePlaceholder":173},[239,4202,4203,4205,4208,4210,4212,4214,4216,4218,4220],{"class":241,"line":812},[239,4204,3971],{"class":393},[239,4206,4207],{"class":244}," setParent",[239,4209,401],{"class":400},[239,4211,2676],{"class":410},[239,4213,699],{"class":400},[239,4215,4062],{"class":410},[239,4217,2928],{"class":400},[239,4219,4162],{"class":417},[239,4221,1355],{"class":400},[239,4223,4224,4226,4228,4230,4232,4235],{"class":241,"line":820},[239,4225,2802],{"class":410},[239,4227,699],{"class":400},[239,4229,4062],{"class":410},[239,4231,2928],{"class":400},[239,4233,4234],{"class":244},"getParent",[239,4236,710],{"class":400},[239,4238,4239],{"class":241,"line":1445},[239,4240,3583],{"class":393},[239,4242,4243,4246],{"class":241,"line":1468},[239,4244,4245],{"class":244},"    C",[239,4247,3769],{"class":400},[239,4249,4250],{"class":241,"line":1487},[239,4251,2843],{"class":400},[239,4253,4254],{"class":241,"line":1495},[239,4255,823],{"class":400},[239,4257,4258],{"class":241,"line":1534},[239,4259,445],{"emptyLinePlaceholder":173},[239,4261,4262,4264,4266,4268,4270],{"class":241,"line":1565},[239,4263,3613],{"class":400},[239,4265,699],{"class":393},[239,4267,4062],{"class":400},[239,4269,2810],{"class":393},[239,4271,3622],{"class":400},[239,4273,4274,4276,4278,4280,4282],{"class":241,"line":1572},[239,4275,2802],{"class":400},[239,4277,699],{"class":393},[239,4279,4062],{"class":400},[239,4281,2810],{"class":393},[239,4283,4284],{"class":400}," _parent;\n",[239,4286,4287,4290,4292,4294,4296,4298,4300,4303],{"class":241,"line":1577},[239,4288,4289],{"class":400},"    QList",[239,4291,699],{"class":393},[239,4293,3182],{"class":400},[239,4295,699],{"class":393},[239,4297,4062],{"class":400},[239,4299,2810],{"class":393},[239,4301,4302],{"class":393}," >",[239,4304,4305],{"class":400}," _childs;\n",[239,4307,4308],{"class":241,"line":3991},[239,4309,1073],{"class":400},[11,4311,4312],{},"Dans ces cas là, on a :- L'objet A possède la référence vers l'objet B-\nL'objet B possède une référence vers l'objet A.- Même principe avec\nl'objet C",[11,4314,4315],{},[49,4316],{"alt":4317,"src":4318},"Reference circulaire de QSharedPointer","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer3.png",[11,4320,4321],{},"Dans ce cas, il restera alors toujours une référence vers A, et une vers\nB, même si plus aucune variable ne référence ces objets. Cette référence\ncirculaire fait que l'objet ne sera jamais détruit même si on n'a plus\nbesoin de l'objet.",[11,4323,4324],{},"Si on décide que l'objet A sera l'objet maitre (donc que sa destruction\nengendrera la destruction de l'objet B), on peut alors écrire les choses\nainsi pour l'objet B :",[230,4326,4328],{"className":384,"code":4327,"language":386,"meta":42,"style":42},"class B\n{\npublic:\n    static QSharedPointer\u003CB> create()\n    {\n        QSharedPointer\u003CB> ptr(new B());\n        return ptr;\n    }\n    void setA(QWeakPointer\u003CA> b);\n    QWeakPointer\u003CA> getA();\nprivate:\n    QWeakPointer\u003CA>  a;\n};\n",[236,4329,4330,4336,4340,4344,4360,4364,4384,4390,4394,4414,4428,4432,4444],{"__ignoreMap":42},[239,4331,4332,4334],{"class":241,"line":181},[239,4333,3487],{"class":393},[239,4335,3907],{"class":410},[239,4337,4338],{"class":241,"line":135},[239,4339,2792],{"class":400},[239,4341,4342],{"class":241,"line":260},[239,4343,3499],{"class":393},[239,4345,4346,4348,4350,4352,4354,4356,4358],{"class":241,"line":448},[239,4347,3504],{"class":393},[239,4349,3182],{"class":410},[239,4351,699],{"class":400},[239,4353,3875],{"class":410},[239,4355,2928],{"class":400},[239,4357,3515],{"class":244},[239,4359,3769],{"class":400},[239,4361,4362],{"class":241,"line":476},[239,4363,2843],{"class":400},[239,4365,4366,4368,4370,4372,4374,4376,4378,4380,4382],{"class":241,"line":498},[239,4367,3533],{"class":400},[239,4369,699],{"class":393},[239,4371,3875],{"class":400},[239,4373,2810],{"class":393},[239,4375,2813],{"class":244},[239,4377,401],{"class":400},[239,4379,2763],{"class":393},[239,4381,3954],{"class":244},[239,4383,771],{"class":400},[239,4385,4386,4388],{"class":241,"line":503},[239,4387,690],{"class":393},[239,4389,2975],{"class":400},[239,4391,4392],{"class":241,"line":509},[239,4393,823],{"class":400},[239,4395,4396,4398,4400,4402,4404,4406,4408,4410,4412],{"class":241,"line":524},[239,4397,3971],{"class":393},[239,4399,3974],{"class":244},[239,4401,401],{"class":400},[239,4403,3003],{"class":410},[239,4405,699],{"class":400},[239,4407,3782],{"class":410},[239,4409,2928],{"class":400},[239,4411,1175],{"class":417},[239,4413,1355],{"class":400},[239,4415,4416,4418,4420,4422,4424,4426],{"class":241,"line":541},[239,4417,3613],{"class":410},[239,4419,699],{"class":400},[239,4421,3782],{"class":410},[239,4423,2928],{"class":400},[239,4425,4002],{"class":244},[239,4427,710],{"class":400},[239,4429,4430],{"class":241,"line":564},[239,4431,3583],{"class":393},[239,4433,4434,4436,4438,4440,4442],{"class":241,"line":569},[239,4435,3613],{"class":400},[239,4437,699],{"class":393},[239,4439,3782],{"class":400},[239,4441,2810],{"class":393},[239,4443,4023],{"class":400},[239,4445,4446],{"class":241,"line":585},[239,4447,1073],{"class":400},[11,4449,4450,4451,4453,4454,114,4456,4458,4459,4467,4468,45],{},"Dans ce cas, avec l'utilisation d'un ",[236,4452,3003],{},", lorsque qu'il\nn'existera plus de référence vers l'objet A, le pointeur ",[209,4455,2999],{},[236,4457,37],{},"\nsera mis à jour comme ne contenant plus de référence",[34,4460,4461],{},[37,4462,4466],{"href":4463,"ariaDescribedBy":4464,"dataFootnoteRef":42,"id":4465},"#user-content-fn-6",[41],"user-content-fnref-6","6",".\nL'instance de l'objet A sera réellement détruite. Il n'y aura alors plus\naucune référence vers l'objet B qui sera alors également\ndétruit",[34,4469,4470],{},[37,4471,4475],{"href":4472,"ariaDescribedBy":4473,"dataFootnoteRef":42,"id":4474},"#user-content-fn-7",[41],"user-content-fnref-7","7",[2184,4477,4479],{"id":4478},"utilisation-dans-les-applications-multi-thread","Utilisation dans les applications multi-thread",[11,4481,4482,4483,4485,4486,2367,4488,4490],{},"L'utilisation de ",[236,4484,2676],{}," simplifie l'écriture des applications\nmulti-thread (les objets ",[236,4487,2676],{},[236,4489,3003],{}," sont\nthread-safe).",[11,4492,4493,4494,4502,4503,45],{},"Dans ces applications il n'y a alors plus besoin de se soucier si\nl'objet est en cours d'utilisation ailleurs dans l'application avant de\nle supprimer",[34,4495,4496],{},[37,4497,4501],{"href":4498,"ariaDescribedBy":4499,"dataFootnoteRef":42,"id":4500},"#user-content-fn-8",[41],"user-content-fnref-8","8",". Lorsqu'un pointeur ne devient plus utilisé dans\nun thread donné, il ne sera détruit que s'il n'y a pas d'autres\nréférences dans d'autres threads de l'application",[34,4504,4505],{},[37,4506,4510],{"href":4507,"ariaDescribedBy":4508,"dataFootnoteRef":42,"id":4509},"#user-content-fn-9",[41],"user-content-fnref-9","9",[11,4512,4513,4514,4516,4517,45],{},"Avec l'utilisation de ",[236,4515,3003],{},", un thread pourra tester\nl'existence du pointeur avant d'effectuer une opération et pourra aviser\nle cas échéant sans faire planter toute l'application",[34,4518,4519],{},[37,4520,678],{"href":4521,"ariaDescribedBy":4522,"dataFootnoteRef":42,"id":4523},"#user-content-fn-10",[41],"user-content-fnref-10",[2184,4525,4527],{"id":4526},"utilisation-dun-pool","Utilisation d'un pool",[11,4529,4530,4531,4536],{},"Si la création et la destruction d'un objet est coûteux, il est\nenvisageable de diminuer le coût de destruction et de création d'un\nthread en utilisant un Pool d'objet. Dans ce cas l'objet ",[37,4532,4535],{"href":4533,"rel":4534},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqqueue.html",[113],"QQueue","\npourra être utilisé pour représenter notre Pool.",[11,4538,4539,4540,4542,4543,45],{},"Lors de la demande de création, en utilisant notre méthode ",[236,4541,3515],{},"\nci-dessus, on prend alors une valeur du pool (si disponible) et on la\nretourne sous forme d'un ",[236,4544,2676],{},[230,4546,4548],{"className":384,"code":4547,"language":386,"meta":42,"style":42},"QSharedPointer\u003CMyObject> MyObject::create()\n{\n    MyObject * c_ptr;\n    if (_queue.size())\n    {\n    c_ptr = _queue.dequeue();\n    }\n    else\n    {\n    c_ptr = new MyObject();\n    }\n    QSharedPointer\u003CMyObject> ptr(c_ptr, ReturnToPool);\n    ptr->_this = ptr.toWeakRef();\n    return ptr;\n}\n",[236,4549,4550,4568,4572,4582,4599,4603,4620,4624,4629,4633,4645,4649,4664,4682,4689],{"__ignoreMap":42},[239,4551,4552,4554,4556,4558,4560,4562,4564,4566],{"class":241,"line":181},[239,4553,2676],{"class":410},[239,4555,699],{"class":400},[239,4557,2807],{"class":410},[239,4559,2928],{"class":400},[239,4561,2807],{"class":410},[239,4563,1168],{"class":400},[239,4565,3515],{"class":244},[239,4567,3769],{"class":400},[239,4569,4570],{"class":241,"line":135},[239,4571,2792],{"class":400},[239,4573,4574,4577,4579],{"class":241,"line":260},[239,4575,4576],{"class":400},"    MyObject ",[239,4578,760],{"class":393},[239,4580,4581],{"class":400}," c_ptr;\n",[239,4583,4584,4586,4588,4591,4593,4596],{"class":241,"line":448},[239,4585,660],{"class":393},[239,4587,741],{"class":400},[239,4589,4590],{"class":410},"_queue",[239,4592,45],{"class":400},[239,4594,4595],{"class":244},"size",[239,4597,4598],{"class":400},"())\n",[239,4600,4601],{"class":241,"line":476},[239,4602,2843],{"class":400},[239,4604,4605,4608,4610,4613,4615,4618],{"class":241,"line":498},[239,4606,4607],{"class":400},"    c_ptr ",[239,4609,547],{"class":393},[239,4611,4612],{"class":410}," _queue",[239,4614,45],{"class":400},[239,4616,4617],{"class":244},"dequeue",[239,4619,710],{"class":400},[239,4621,4622],{"class":241,"line":503},[239,4623,823],{"class":400},[239,4625,4626],{"class":241,"line":509},[239,4627,4628],{"class":393},"    else\n",[239,4630,4631],{"class":241,"line":524},[239,4632,2843],{"class":400},[239,4634,4635,4637,4639,4641,4643],{"class":241,"line":541},[239,4636,4607],{"class":400},[239,4638,547],{"class":393},[239,4640,2039],{"class":393},[239,4642,2820],{"class":244},[239,4644,710],{"class":400},[239,4646,4647],{"class":241,"line":564},[239,4648,823],{"class":400},[239,4650,4651,4653,4655,4657,4659,4661],{"class":241,"line":569},[239,4652,2802],{"class":400},[239,4654,699],{"class":393},[239,4656,2807],{"class":400},[239,4658,2810],{"class":393},[239,4660,2813],{"class":244},[239,4662,4663],{"class":400},"(c_ptr, ReturnToPool);\n",[239,4665,4666,4668,4670,4672,4674,4676,4678,4680],{"class":241,"line":585},[239,4667,2942],{"class":410},[239,4669,2750],{"class":400},[239,4671,3465],{"class":606},[239,4673,1986],{"class":393},[239,4675,2813],{"class":410},[239,4677,45],{"class":400},[239,4679,3031],{"class":244},[239,4681,710],{"class":400},[239,4683,4684,4687],{"class":241,"line":590},[239,4685,4686],{"class":393},"    return",[239,4688,2975],{"class":400},[239,4690,4691],{"class":241,"line":652},[239,4692,1580],{"class":400},[11,4694,4695,4696,4704,4705,4707],{},"Dans l'exemple ci-dessus",[34,4697,4698],{},[37,4699,4703],{"href":4700,"ariaDescribedBy":4701,"dataFootnoteRef":42,"id":4702},"#user-content-fn-11",[41],"user-content-fnref-11","11",", on demande à la queue, qui doit\nêtre une variable globale ou statique, un élément, et si ce n'est pas\npossible, on crée un nouvel objet de type ",[236,4706,2807],{}," (dont on suppose la\ncréation coûteuse).",[11,4709,4710,4711,4713,4714,4717,4718,4721,4722,4725],{},"Lors de la création du ",[236,4712,2676],{}," on utilise alors le constructeur\n",[236,4715,4716],{},"QSharedPointer ( T * ptr, Deleter deleter )"," sur lequel on définit une\nméthode ",[236,4719,4720],{},"Deleter"," nommée ",[236,4723,4724],{},"ReturnToPool"," dont le but est de remettre les\nobjets en pool.",[230,4727,4729],{"className":384,"code":4728,"language":386,"meta":42,"style":42},"static void ReturnToPool(MyObject *obj)\n{\n    if (_queue.size() \u003C MAX_SIZE_QUEUE)\n    {\n        _queue.enqueue(obj);\n    }\n    else\n    {\n        delete obj;\n    }\n}\n",[236,4730,4731,4752,4756,4775,4779,4792,4796,4800,4804,4811,4815],{"__ignoreMap":42},[239,4732,4733,4736,4739,4742,4744,4746,4748,4750],{"class":241,"line":181},[239,4734,4735],{"class":393},"static",[239,4737,4738],{"class":393}," void",[239,4740,4741],{"class":244}," ReturnToPool",[239,4743,401],{"class":400},[239,4745,2807],{"class":410},[239,4747,787],{"class":393},[239,4749,1978],{"class":417},[239,4751,2933],{"class":400},[239,4753,4754],{"class":241,"line":135},[239,4755,2792],{"class":400},[239,4757,4758,4760,4762,4764,4766,4768,4770,4772],{"class":241,"line":260},[239,4759,660],{"class":393},[239,4761,741],{"class":400},[239,4763,4590],{"class":410},[239,4765,45],{"class":400},[239,4767,4595],{"class":244},[239,4769,757],{"class":400},[239,4771,699],{"class":393},[239,4773,4774],{"class":400}," MAX_SIZE_QUEUE)\n",[239,4776,4777],{"class":241,"line":448},[239,4778,2843],{"class":400},[239,4780,4781,4784,4786,4789],{"class":241,"line":476},[239,4782,4783],{"class":410},"        _queue",[239,4785,45],{"class":400},[239,4787,4788],{"class":244},"enqueue",[239,4790,4791],{"class":400},"(obj);\n",[239,4793,4794],{"class":241,"line":498},[239,4795,823],{"class":400},[239,4797,4798],{"class":241,"line":503},[239,4799,4628],{"class":393},[239,4801,4802],{"class":241,"line":509},[239,4803,2843],{"class":400},[239,4805,4806,4809],{"class":241,"line":524},[239,4807,4808],{"class":393},"        delete",[239,4810,3387],{"class":400},[239,4812,4813],{"class":241,"line":541},[239,4814,823],{"class":400},[239,4816,4817],{"class":241,"line":564},[239,4818,1580],{"class":400},[11,4820,4821],{},"Dans ce cas de retour au pool, si le pool est rempli, on détruit l'objet\n(pour éviter de consommer trop de mémoire), sinon on l'ajoute au pool.\nDans ce cas, le pool est agrandi au fur et à mesure des besoins, jusqu'à\nune taille limite.",[11,4823,4824],{},"Bien sûr il faut que la performance de l'utilisation d'un pool soit plus\nintéressante que celle de la création de l'objet et de son\ninitialisation.",[11,4826,4827],{},[18,4828,4829,4833,4834,4836,4837,4840,4841,4843,4844,4846,4847,4849,4850,4852,4853],{},[4830,4831,4832],"ins",{},"Attention"," : Ce point ne fonctionne, par contre, pas si\nl'objet (",[236,4835,2807],{},") est un descendant de ",[236,4838,4839],{},"QObject",". En effet ",[236,4842,4839],{},"\ngarde une référence du ",[236,4845,2676],{}," en mémoire et lors de la\nréutilisation du ",[236,4848,4839],{}," une erreur indique que l'objet n'a pas été\ndétruit et est déjà utilisé par un ",[236,4851,2676],{},". On n'a pas le\nproblème avec ",[236,4854,4855],{},"std::tr1::shared_ptr",[190,4857,4859],{"id":4858},"benchmark","Benchmark",[11,4861,4862,4863,4865],{},"Le but du benchmark est de se faire une idée sur les performances d'une\napplication utilisant des ",[236,4864,2676],{}," à la place des pointeurs\nnormaux. Attention, ce bench ne prend pas en compte le besoin potentiel\nde Mutex, de comptage de référence manuel, ... dans les applications\nmulti-thread qui pourrait être nécessaire pour ne pas supprimer le\npointeur si besoin.",[11,4867,4868,4869,4871,4872,45],{},"Dans ce test nous allons tester également (en comparaison), le pointeur\n",[209,4870,2601],{}," du C++0x",[34,4873,4874],{},[37,4875,4879],{"href":4876,"ariaDescribedBy":4877,"dataFootnoteRef":42,"id":4878},"#user-content-fn-12",[41],"user-content-fnref-12","12",[11,4881,4882],{},"Nous allons donc tester les opérations courantes de création,\ndestruction, modification, affectation.",[2184,4884,4886],{"id":4885},"code-source","Code source",[11,4888,4889,4890,4893],{},"Le code source est disponible, attaché au billet. Dans la suite du\nbillet, seuls les morceaux intéressants du benchmark seront décris. Le\nbenchmark utilise QTest. Nous avons créé un objet bidon ",[236,4891,4892],{},"ObjetTest"," qui\ndans le constructeur allouera un pointeur et remplira une liste, et le\ndestructeur supprime ce pointeur (et forcément la liste).",[11,4895,4896],{},"Pour que chaque test soit indépendant, le jeu de test sera initialisé\navant le début de chaque QBENCHMARK et détruit à la fin du bloc. Nous\naurons quatre méthodes :",[333,4898,4899,4902,4905,4908],{},[106,4900,4901],{},"Allocation",[106,4903,4904],{},"Modification",[106,4906,4907],{},"Affectation",[106,4909,4910],{},"Nettoyage",[11,4912,4913],{},"Pour chaque test nous allons faire le test avec",[333,4915,4916,4919,4927],{},[106,4917,4918],{},"un pointeur C standard",[106,4920,4921,4922,4924,4925],{},"le pointeur ",[236,4923,2676],{}," de ",[209,4926,2588],{},[106,4928,4921,4929,4924,4931],{},[236,4930,4855],{},[209,4932,4933],{},"C++0x",[11,4935,4936],{},"Pour le test d'allocation et le test de nettoyage, nous allons également\nutiliser l'optimisation possible, vu ci-dessus, d'un Pool d'objet. Nous\nallons faire le test avec :",[333,4938,4939,4945],{},[106,4940,4921,4941,4924,4943],{},[236,4942,2676],{},[209,4944,2588],{},[106,4946,4921,4947,4924,4949],{},[236,4948,4855],{},[209,4950,4933],{},[2184,4952,4954],{"id":4953},"le-jeu-de-test","Le jeu de test",[4956,4957,4959],"h5",{"id":4958},"test-de-lallocation","Test de l'allocation",[11,4961,4962,4963,4965,4966,4968],{},"La création du pointeur en utilisant ",[236,4964,2676],{}," instancie le\npointeur ainsi que le ",[236,4967,2676],{},". Le temps d'exécution est donc\npotentiellement deux fois plus long (voir le benchmark à la fin de ce\nbillet).",[11,4970,4971],{},"Pour la création du pool, nous allons utiliser une méthode qui créera le\npointeur s'il n'est pas dans le pool, et sinon prendra le pointeur du\npool. Dans notre cas de test, il y aura toujours une valeur dans le\npool, que l'on aura rempli au préalable.",[11,4973,4974,4975,2367,4978,4981],{},"La méthode ",[236,4976,4977],{},"createFromPool()",[236,4979,4980],{},"createFromBoostPool()"," est\nsensiblement identique :",[230,4983,4985],{"className":384,"code":4984,"language":386,"meta":42,"style":42},"QSharedPointer\u003CObjetTest> createFromPool()\n{\n    ObjetTest * c_ptr;\n    if (_queue.size())\n    {\n        c_ptr = _queue.dequeue();\n    }\n    else\n    {\n        c_ptr = new ObjetTest();\n    }\n\n    QSharedPointer\u003CObjetTest> ptr(c_ptr, returnToPool);\n    return ptr;\n}\n",[236,4986,4987,5002,5006,5015,5029,5033,5048,5052,5056,5060,5073,5077,5081,5096,5102],{"__ignoreMap":42},[239,4988,4989,4991,4993,4995,4997,5000],{"class":241,"line":181},[239,4990,2676],{"class":410},[239,4992,699],{"class":400},[239,4994,4892],{"class":410},[239,4996,2928],{"class":400},[239,4998,4999],{"class":244},"createFromPool",[239,5001,3769],{"class":400},[239,5003,5004],{"class":241,"line":135},[239,5005,2792],{"class":400},[239,5007,5008,5011,5013],{"class":241,"line":260},[239,5009,5010],{"class":400},"    ObjetTest ",[239,5012,760],{"class":393},[239,5014,4581],{"class":400},[239,5016,5017,5019,5021,5023,5025,5027],{"class":241,"line":448},[239,5018,660],{"class":393},[239,5020,741],{"class":400},[239,5022,4590],{"class":410},[239,5024,45],{"class":400},[239,5026,4595],{"class":244},[239,5028,4598],{"class":400},[239,5030,5031],{"class":241,"line":476},[239,5032,2843],{"class":400},[239,5034,5035,5038,5040,5042,5044,5046],{"class":241,"line":498},[239,5036,5037],{"class":400},"        c_ptr ",[239,5039,547],{"class":393},[239,5041,4612],{"class":410},[239,5043,45],{"class":400},[239,5045,4617],{"class":244},[239,5047,710],{"class":400},[239,5049,5050],{"class":241,"line":503},[239,5051,823],{"class":400},[239,5053,5054],{"class":241,"line":509},[239,5055,4628],{"class":393},[239,5057,5058],{"class":241,"line":524},[239,5059,2843],{"class":400},[239,5061,5062,5064,5066,5068,5071],{"class":241,"line":541},[239,5063,5037],{"class":400},[239,5065,547],{"class":393},[239,5067,2039],{"class":393},[239,5069,5070],{"class":244}," ObjetTest",[239,5072,710],{"class":400},[239,5074,5075],{"class":241,"line":564},[239,5076,823],{"class":400},[239,5078,5079],{"class":241,"line":569},[239,5080,445],{"emptyLinePlaceholder":173},[239,5082,5083,5085,5087,5089,5091,5093],{"class":241,"line":585},[239,5084,2802],{"class":400},[239,5086,699],{"class":393},[239,5088,4892],{"class":400},[239,5090,2810],{"class":393},[239,5092,2813],{"class":244},[239,5094,5095],{"class":400},"(c_ptr, returnToPool);\n",[239,5097,5098,5100],{"class":241,"line":590},[239,5099,4686],{"class":393},[239,5101,2975],{"class":400},[239,5103,5104],{"class":241,"line":652},[239,5105,1580],{"class":400},[5107,5108,5109,5122],"table",{},[5110,5111,5112],"thead",{},[5113,5114,5115,5119],"tr",{},[5116,5117,5118],"th",{},"Méthode",[5116,5120,5121],{},"Code",[5123,5124,5125,5136,5146,5156,5166],"tbody",{},[5113,5126,5127,5131],{},[5128,5129,5130],"td",{},"C Pointer",[5128,5132,5133],{},[236,5134,5135],{},"ObjetTest* ptr = new ObjetTest();",[5113,5137,5138,5141],{},[5128,5139,5140],{},"Qt Smart Pointer",[5128,5142,5143],{},[236,5144,5145],{},"QSharedPointer\u003CObjetTest> ptr(new ObjetTest());",[5113,5147,5148,5151],{},[5128,5149,5150],{},"Qt Smart Pointer as Pool",[5128,5152,5153],{},[236,5154,5155],{},"QSharedPointer\u003CObjetTest> ptr = createFromPool ();",[5113,5157,5158,5161],{},[5128,5159,5160],{},"C++0x Smart Pointer",[5128,5162,5163],{},[236,5164,5165],{},"std::tr1::shared_ptr\u003CObjetTest> ptr(new ObjetTest());",[5113,5167,5168,5171],{},[5128,5169,5170],{},"C++0x Smart Pointer as Pool",[5128,5172,5173],{},[236,5174,5175],{},"std::tr1::shared_ptr\u003CObjetTest> ptr = createFromBoostPool ();",[4956,5177,5179],{"id":5178},"test-de-modification-dune-donnée","Test de Modification d'une donnée",[11,5181,5182],{},"Pour la modification d'une donnée, on génère un nombre aléatoire que\nl'on va stocker (toujours le même pour chaque test, cela n'a pas\nd'importance). La génération du nombre aléatoire se fait en dehors du\nbloc, pour éviter de polluer le test avec le calcul d'un nombre\naléatoire. Ici il n'y a pas création d'affectation du pointeur, juste\nune affectation d'une valeur dans le contenu du pointeur. La syntaxe\npour le C, et pour le pointeur intelligent est identique.",[5107,5184,5185,5193],{},[5110,5186,5187],{},[5113,5188,5189,5191],{},[5116,5190,5118],{},[5116,5192,5121],{},[5123,5194,5195],{},[5113,5196,5197,5200],{},[5128,5198,5199],{},"C Pointer \u002F Qt Smart Pointer \u002F C++0x Smart Pointer",[5128,5201,5202],{},[236,5203,5204],{},"obj->value = random_number;",[4956,5206,5208],{"id":5207},"test-daffectation","Test d'affectation",[11,5210,5211,5212,5214],{},"Pour l'affectation nous allons créer une nouvelle variable qui pointera\nsur le même pointeur, et sur lequel on fera une modification. La\ncréation d'un pointeur peut arriver par exemple lors du passage du\npointeur à une fonction, ou lors de la déclaration d'une variable devant\ncontenir la même valeur. Cette déclaration supplémentaire a peu d'impact\npour un pointeur C mais pour un pointeur ",[209,5213,2601],{}," oblige la\ncréation d'un objet, et l'incrément d'un nombre d'instance (qu'on\ndécrémente ici dans la même boucle).",[5107,5216,5217,5225],{},[5110,5218,5219],{},[5113,5220,5221,5223],{},[5116,5222,5118],{},[5116,5224,5121],{},[5123,5226,5227,5236,5245,5254,5262,5271],{},[5113,5228,5229,5231],{},[5128,5230,5130],{},[5128,5232,5233],{},[236,5234,5235],{},"ObjetTest * obj2 = obj;",[5113,5237,5238,5240],{},[5128,5239],{},[5128,5241,5242],{},[236,5243,5244],{},"obj2->value = random_number;",[5113,5246,5247,5249],{},[5128,5248,5140],{},[5128,5250,5251],{},[236,5252,5253],{},"QSharedPointer\u003CObjetTest> obj2 = obj;",[5113,5255,5256,5258],{},[5128,5257],{},[5128,5259,5260],{},[236,5261,5244],{},[5113,5263,5264,5266],{},[5128,5265,5160],{},[5128,5267,5268],{},[236,5269,5270],{},"std::tr1::shared_ptr\u003CObjetTest> obj2 = obj;",[5113,5272,5273,5275],{},[5128,5274],{},[5128,5276,5277],{},[236,5278,5244],{},[4956,5280,5282],{"id":5281},"test-de-destruction","Test de destruction",[11,5284,5285,5286,5289],{},"Pour ce test, nous allons initialiser une liste de pointeur, et pour le\nbenchmark, nous allons supprimer un à un chaque élément de la liste.La\ndestruction du pointeur en C se fait par un ",[236,5287,5288],{},"delete",". Pour le pointeur\n''intelligent', il n'y a pas de destruction explicite. Nous allons juste\nsupprimer le pointeur de la liste, le pointeur sera alors\nautomatiquement détruit car il n'y aura plus de référence vers ce\npointeur.",[11,5291,5292,5293,2904],{},"Pour le cas de test utilisant la notion du Pool, on aura créé le\npointeur avec le delete ",[236,5294,5295],{},"returnToPool()",[230,5297,5299],{"className":384,"code":5298,"language":386,"meta":42,"style":42},"void returnToPool(ObjetTest *obj)\n{\n    _queue.enqueue(obj);\n}\n",[236,5300,5301,5318,5322,5333],{"__ignoreMap":42},[239,5302,5303,5305,5308,5310,5312,5314,5316],{"class":241,"line":181},[239,5304,2914],{"class":393},[239,5306,5307],{"class":244}," returnToPool",[239,5309,401],{"class":400},[239,5311,4892],{"class":410},[239,5313,787],{"class":393},[239,5315,1978],{"class":417},[239,5317,2933],{"class":400},[239,5319,5320],{"class":241,"line":135},[239,5321,2792],{"class":400},[239,5323,5324,5327,5329,5331],{"class":241,"line":260},[239,5325,5326],{"class":410},"    _queue",[239,5328,45],{"class":400},[239,5330,4788],{"class":244},[239,5332,4791],{"class":400},[239,5334,5335],{"class":241,"line":448},[239,5336,1580],{"class":400},[11,5338,5339],{},"Cette méthode ne fait pas de réelle destruction, mais juste un ajout de\nl'objet au pool.",[5107,5341,5342,5350],{},[5110,5343,5344],{},[5113,5345,5346,5348],{},[5116,5347,5118],{},[5116,5349,5121],{},[5123,5351,5352,5361,5370,5379,5385,5391],{},[5113,5353,5354,5356],{},[5128,5355,5130],{},[5128,5357,5358],{},[236,5359,5360],{},"delete c_ptr_list.at(0);",[5113,5362,5363,5365],{},[5128,5364],{},[5128,5366,5367],{},[236,5368,5369],{},"c_ptr_list.removeFirst ();",[5113,5371,5372,5374],{},[5128,5373,5140],{},[5128,5375,5376],{},[236,5377,5378],{},"smart_ptr_list.removeFirst ();",[5113,5380,5381,5383],{},[5128,5382,5150],{},[5128,5384],{},[5113,5386,5387,5389],{},[5128,5388,5160],{},[5128,5390],{},[5113,5392,5393,5395],{},[5128,5394,5170],{},[5128,5396],{},[4956,5398,5400],{"id":5399},"résultat-du-test","Résultat du test",[11,5402,5403],{},"Le test a été fait en utilisant la version 4.6.3 de Qt. Test effectué\npour 5 000 000 itérations.",[5107,5405,5406,5427],{},[5110,5407,5408],{},[5113,5409,5410,5412,5415,5418,5421,5424],{},[5116,5411],{},[5116,5413,5414],{},"Pointeur C",[5116,5416,5417],{},"Pointeur Qt",[5116,5419,5420],{},"Pointeur C++0x",[5116,5422,5423],{},"Pool en utilisant QSharedPointer",[5116,5425,5426],{},"Pool en utilisant std::tr1::shared_ptr",[5123,5428,5429,5450,5468,5486],{},[5113,5430,5431,5435,5438,5441,5444,5447],{},[5128,5432,5433],{},[236,5434,4901],{},[5128,5436,5437],{},"0.0004275 msec",[5128,5439,5440],{},"0.0007692 msec",[5128,5442,5443],{},"0.0006604 msec",[5128,5445,5446],{},"0.0002590 msec",[5128,5448,5449],{},"0.0002286 msec",[5113,5451,5452,5456,5459,5462,5464,5466],{},[5128,5453,5454],{},[236,5455,4904],{},[5128,5457,5458],{},"0.000010 msec",[5128,5460,5461],{},"0.000012 msec",[5128,5463,5461],{},[5128,5465],{},[5128,5467],{},[5113,5469,5470,5474,5476,5479,5482,5484],{},[5128,5471,5472],{},[236,5473,4907],{},[5128,5475,5458],{},[5128,5477,5478],{},"0.0000386 msec",[5128,5480,5481],{},"0.0000230 msec",[5128,5483],{},[5128,5485],{},[5113,5487,5488,5493,5496,5499,5502,5505],{},[5128,5489,5490],{},[236,5491,5492],{},"Destruction",[5128,5494,5495],{},"0.000190 msec",[5128,5497,5498],{},"0.0003161 msec",[5128,5500,5501],{},"0.0003359 msec",[5128,5503,5504],{},"0.0004003 msec",[5128,5506,5507],{},"0.0003601 msec",[11,5509,5510,5511,5513],{},"Conclusion que l'on peut en tirer, le pointeur C est ce qu'il y a de\nplus rapide à partir du moment où on fait de l'allocation de\nl'affectation ou de la destruction. Par contre il n'apporte pas la\nsouplesse qu'apporte les pointeurs ",[209,5512,2621],{}," entre autre pour les\napplications multi-threadé.",[11,5515,5516],{},"On remarque que le pointeur C++0x est plus rapide pour la création, mais\napparemment plus lent en destruction. Il est également possible avec le\npool de gagner en performance (surtout en création). Par contre le coût\nde destruction de l'objet n'est pas encore assez fort pour y gagner en\nutilisant le pool.",[11,5518,5519],{},"Ensuite il est important de se faire son propre jugement selon ses\nbesoins. Si besoin le source est attaché, vous pouvez faire vos propres\ntests.",[4956,5521,5523],{"id":5522},"source-du-test","Source du test",[11,5525,5526,5527,45],{},"Vous pouvez trouver les sources du test au ",[37,5528,5530],{"href":5529},"\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002Fsmart_benchmark.7z","lien suivant",[11,5532,5533,5538,5539,5544,5545,45],{},[37,5534,5537],{"href":5535,"rel":5536},"http:\u002F\u002Fwww.boost.org\u002Fdoc\u002Flibs\u002F1_45_0\u002Flibs\u002Fsmart_ptr\u002Fshared_ptr.htm",[113],"boost::shared_ptr"," du projet ",[37,5540,5543],{"href":5541,"rel":5542},"http:\u002F\u002Fwww.boost.org\u002F",[113],"Boost",". Boost est une librairie qui\najoute beaucoup de facilité pour les programmes en C++, comme par\nexemple les smart-pointer dont certains seront inclus dans C++0x, ou de\nla boucle ",[236,5546,5547],{},"std::for_each",[92,5549,5551,5554],{"className":5550,"dataFootnotes":42},[95],[97,5552,101],{"className":5553,"id":41},[100],[103,5555,5556,5562,5568,5579,5598,5607,5620,5629,5641,5650,5664,5673],{},[106,5557,5558,5559],{"id":108},"en anglais : smart-pointer ",[37,5560,121],{"href":117,"ariaLabel":118,"className":5561,"dataFootnoteBackref":42},[120],[106,5563,5564,5565],{"id":124},"COW = Copy On Write ",[37,5566,121],{"href":131,"ariaLabel":132,"className":5567,"dataFootnoteBackref":42},[120],[106,5569,5571,5572,114,5574],{"id":5570},"user-content-fn-3","Ce pointeur est l'équivalent du pointeur ",[209,5573,2601],{},[37,5575,121],{"href":5576,"ariaLabel":5577,"className":5578,"dataFootnoteBackref":42},"#user-content-fnref-3","Back to reference 3",[120],[106,5580,5582,5583,5586,5587,5589,5590,5592,5593],{"id":5581},"user-content-fn-4","Si à un moment donné il faut utiliser le pointeur C pour une\nraison quelconque, on peut utiliser ",[236,5584,5585],{},"ptr.data()"," mais il faut s'assurer\nque le pointeur ne sera pas détruit en déclarant un ",[236,5588,2676],{},"\ndans le même bloc utilisant le pointeur C. Le ",[236,5591,2676],{}," ne devra\nêtre détruit qu'après utilisation du pointeur C. Ceci peut être fait\ndans certain cas pour des raisons de performance. ",[37,5594,121],{"href":5595,"ariaLabel":5596,"className":5597,"dataFootnoteBackref":42},"#user-content-fnref-4","Back to reference 4",[120],[106,5599,5601,5602],{"id":5600},"user-content-fn-5","Sinon nous ne serions plus là pour lancer la méthode ",[37,5603,121],{"href":5604,"ariaLabel":5605,"className":5606,"dataFootnoteBackref":42},"#user-content-fnref-5","Back to reference 5",[120],[106,5608,5610,5611,5614,5615],{"id":5609},"user-content-fn-6","Le ",[236,5612,5613],{},"QWeakPointeur"," ne gardant pas d'instance d'objet, car il\nn'incrémente pas le compteur de référence ",[37,5616,121],{"href":5617,"ariaLabel":5618,"className":5619,"dataFootnoteBackref":42},"#user-content-fnref-6","Back to reference 6",[120],[106,5621,5623,5624],{"id":5622},"user-content-fn-7","s'il n'existe pas de référence vers l'objet B ailleurs dans\nl'application ",[37,5625,121],{"href":5626,"ariaLabel":5627,"className":5628,"dataFootnoteBackref":42},"#user-content-fnref-7","Back to reference 7",[120],[106,5630,5632,5633,5635,5636],{"id":5631},"user-content-fn-8","Attention quand même, ",[236,5634,2676],{}," protège le pointeur\nmais pas le contenu ",[37,5637,121],{"href":5638,"ariaLabel":5639,"className":5640,"dataFootnoteBackref":42},"#user-content-fnref-8","Back to reference 8",[120],[106,5642,5644,5645],{"id":5643},"user-content-fn-9","d'autres threads pouvant inclure le thread principal ",[37,5646,121],{"href":5647,"ariaLabel":5648,"className":5649,"dataFootnoteBackref":42},"#user-content-fnref-9","Back to reference 9",[120],[106,5651,5653,5654,5656,5657,114,5659],{"id":5652},"user-content-fn-10","Si l'objet est supprimé, ",[236,5655,3003],{},", sera alors remis à\n",[236,5658,3053],{},[37,5660,121],{"href":5661,"ariaLabel":5662,"className":5663,"dataFootnoteBackref":42},"#user-content-fnref-10","Back to reference 10",[120],[106,5665,5667,5668],{"id":5666},"user-content-fn-11","Dans le code en question, il faudrait ajouter la notion de\nmutex autour de la gestion de la queue, en cas de création parallèle. ",[37,5669,121],{"href":5670,"ariaLabel":5671,"className":5672,"dataFootnoteBackref":42},"#user-content-fnref-11","Back to reference 11",[120],[106,5674,5676,5677,114,5679,5682,5683],{"id":5675},"user-content-fn-12","Le pointeur ",[209,5678,2601],{},[236,5680,5681],{},"shared_ptr"," de C++0x à pour origine\nle pointeur Boost ",[37,5684,121],{"href":5685,"ariaLabel":5686,"className":5687,"dataFootnoteBackref":42},"#user-content-fnref-12","Back to reference 12",[120],[1709,5689,5690],{},"html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}",{"title":42,"searchDepth":135,"depth":135,"links":5692},[5693,5694,5695,5696,5697],{"id":2299,"depth":260,"text":2300},{"id":2689,"depth":260,"text":2690},{"id":2693,"depth":260,"text":2694},{"id":4858,"depth":260,"text":4859},{"id":41,"depth":135,"text":101},"2011-01-25",{"type":8,"value":5700},[5701,5703,5709,5724,5730],[190,5702,2300],{"id":2299},[11,5704,5705,2589,5707,2593],{},[209,5706,2588],{},[209,5708,2592],{},[11,5710,5711,2598,5713,5715,2607,5720,2610,5722,2613],{},[209,5712,2588],{},[209,5714,2601],{},[34,5716,5717],{},[37,5718,44],{"href":39,"ariaDescribedBy":5719,"dataFootnoteRef":42,"id":43},[41],[209,5721,2601],{},[209,5723,2588],{},[11,5725,5726,2618,5728,2622],{},[209,5727,2588],{},[209,5729,2621],{},[333,5731,5732,5747,5757,5762],{},[106,5733,5734,2632,5737,2638,5740,2642,5742,45],{},[37,5735,2631],{"href":2629,"rel":5736},[113],[37,5738,2637],{"href":2635,"rel":5739},[113],[209,5741,2641],{},[34,5743,5744],{},[37,5745,76],{"href":73,"ariaDescribedBy":5746,"dataFootnoteRef":42,"id":75},[41],[106,5748,5749,2632,5752,2658,5755,2661],{},[37,5750,2654],{"href":2652,"rel":5751},[113],[37,5753,2637],{"href":2635,"rel":5754},[113],[209,5756,2601],{},[106,5758,5759,2669],{},[37,5760,2668],{"href":2666,"rel":5761},[113],[106,5763,5764,2677,5767,2686],{},[37,5765,2676],{"href":2674,"rel":5766},[113],[34,5768,5769],{},[37,5770,2685],{"href":2682,"ariaDescribedBy":5771,"dataFootnoteRef":42,"id":2684},[41],{},"\u002Fpost\u002Fqt-performance-de-l-utilisation-de-qsharedpointer",{"title":2579,"description":42},"qt-performance-de-l-utilisation-de-qsharedpointer","posts\u002FProgrammation\u002F2011-01-25-qt-performance-de-l-utilisation-de-qsharedpointer",[180,5778,1754],"performance","XqeYjPQRtPf9XXPuxti7oBEPUUnQd2DT_XGvWB1Y7Ws",{"id":5781,"title":5782,"author":6,"body":5783,"category":138,"categorySlug":139,"date":5877,"description":42,"excerpt":5878,"extension":170,"location":171,"meta":5892,"navigation":173,"path":5893,"published":173,"seo":5894,"slug":5895,"stem":5896,"tags":5897,"timeToRead":135,"__hash__":5898},"posts\u002Fposts\u002FLogiciels\u002F2009-05-23-kmymoney-logiciel-de-compte.md","KMyMoney - Logiciel de compte",{"type":8,"value":5784,"toc":5874},[5785,5790,5793,5799,5802,5808,5817,5823,5826,5832,5839,5842,5848,5851,5857,5860],[11,5786,5787],{},[49,5788],{"alt":51,"src":5789},"\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002Flogo.png",[11,5791,5792],{},"Voilà un bon logiciel sur lequel on peut compter (mouarf ! mouarf !\nmouarf !), KMyMoney est un éditeur de compte. Je l'utilise\nquotidiennement, et je décide donc d'en parler un peu, pour que d'autres\npersonnes puissent s'intéresser aussi à ce logiciel.",[11,5794,5795],{},[49,5796],{"alt":5797,"src":5798},"Summary","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FSummary.png",[11,5800,5801],{},"KMyMoney est un logiciel de gestion de compte pour particulier. Il vous\npermet de gérer plusieurs de vos comptes en banque, en vous permettant\nde saisir les dépenses et les recettes sur chacun de vos comptes.",[11,5803,5804],{},[49,5805],{"alt":5806,"src":5807},"Registres","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FRegistres.png",[11,5809,5810,5811,5816],{},"Vous pouvez également lui indiquer vos échéances (par exemple : forfait\ntéléphone, prêt immobilier",[34,5812,5813],{},[37,5814,44],{"href":39,"ariaDescribedBy":5815,"dataFootnoteRef":42,"id":43},[41],", mais aussi salaire, vos virements\ninternes ou externes, ...) qu'il s'occupera de mettre à jour dans le\nregistre automatiquement ou à votre demande.",[11,5818,5819],{},[49,5820],{"alt":5821,"src":5822},"Echeancier","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FEcheancier.png",[11,5824,5825],{},"Après une année d'utilisation, il vous permet également de sortir un\nrapport détaillé sur vos dépenses et vos recettes suivant les catégories\nsaisies pour vos opérations. Cette information peut vous être très utile\npour voir où se trouve le \"trou\" de votre porte monnaie et ainsi\nfaire une rustine. Il vous permet aussi de vous projeter vers l'avenir\net de faire votre budget pour l'année prochaine. KMyMoney vous offre\npour cela, la saisie de votre budget, ainsi que plusieurs rapports\nd'écart, vous permettant ainsi de retrouver facilement où vous avez\nfinalement dépensé plus que le budget prévu, et où vous avez dépensé\nmoins.",[11,5827,5828],{},[49,5829],{"alt":5830,"src":5831},"Rapport","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FRapport.png",[11,5833,5834,5835,5838],{},"En plus de vos comptes en banque ",[209,5836,5837],{},"normaux",", KMyMoney vous permet\négalement de gérer vos comptes titre, et les actions que vous y avez\nmises. Vous pouvez alors facilement suivre la chute vertigineuse de la\nbourse et votre portefeuille fondre littéralement, mais aussi la\nremontée (on espère), des actions d'ici quelques ... siècles.",[11,5840,5841],{},"Enfin pour les paranos, vos comptes peuvent être cryptés à l'aide de\nvotre clé GnuPG automatiquement par KMyMoney :)",[11,5843,5844],{},[49,5845],{"alt":5846,"src":5847},"Cryptage","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FCryptage.png",[11,5849,5850],{},"Après cette courte présentation, je vous souhaite bon compte ;)",[5852,5853,5854],"blockquote",{},[11,5855,5856],{},"Pour une vie équilibrée, n'oubliez pas de profiter du soleil, au lieu\nde passer votre temps sur votre ordinateur",[11,5858,5859],{},"... en fonction des différents chiffres que vous allez lui entrer.",[92,5861,5863,5866],{"className":5862,"dataFootnotes":42},[95],[97,5864,101],{"className":5865,"id":41},[100],[103,5867,5868],{},[106,5869,5870,5871],{"id":108},"Il s'occupera d'ailleurs de calculer la durée des échéances, ",[37,5872,121],{"href":117,"ariaLabel":118,"className":5873,"dataFootnoteBackref":42},[120],{"title":42,"searchDepth":135,"depth":135,"links":5875},[5876],{"id":41,"depth":135,"text":101},"2009-05-23",{"type":8,"value":5879},[5880,5884,5886,5890],[11,5881,5882],{},[49,5883],{"alt":51,"src":5789},[11,5885,5792],{},[11,5887,5888],{},[49,5889],{"alt":5797,"src":5798},[11,5891,5801],{},{},"\u002Fpost\u002Fkmymoney-logiciel-de-compte",{"title":5782,"description":42},"kmymoney-logiciel-de-compte","posts\u002FLogiciels\u002F2009-05-23-kmymoney-logiciel-de-compte",[180,1754],"GMoM34deHfpP44yg0dNX_5SNO5lCcgbkTT8_04fCe6c",1777582406091]