Bonjour,
On a beau �tre pointu sur certains sujets, il est est d'autres qui r�sistent � notre mani�re d'appr�hender les choses. Sur une grosse partie du futur standard, je n'ai aucun probl�me de compr�hension. Mais sur les rvalue references, je cale tr�s nettement.
Ceci �tant dit, j'en viens � mon probl�me. A toutes fins utiles, voici une information d'importance :
Bien. J'essaie d'impl�menter une surcouche � libxml2 qui corresponde � mes besoins. J'en viens au code de la classe xml::document :
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7 edt@desktop:~/ddcomp$ g++ -v Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
(nullptr, n'�tant aps encore reconnu par g++ 4.4, est en fait un simple #define nullptr 0; �a n'a pas d'importance dans notre cas, mais �a peut en avoir si vous avez envie de compiler le code).
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 namespace xml { document&& read_xml_file(const std::string& path) { xmlDocPtr xmldoc = xmlReadFile(path.c_str(), NULL, 0); if (xmldoc) { return std::move(document(xmldoc)); } std::stringstream stream; stream << "cannot parse '" << path << "' as an XML file"; throw std::invalid_argument(stream.str()); } document::document(xmlDocPtr xmldoc) : m_doc(xmldoc) { } document::document(document&& other) : m_doc(other.m_doc) { other.m_doc = nullptr; } document::~document() { if (m_doc) { xmlFreeDoc(m_doc); } } }
Ce code est ainsi utilis� :
Dans mon esprit, les choses suivantes devraient se passer :
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4 { xml::document d = xml::read_xml_file(path_to_file); }
1) cr�ation d'une instance de xml::document()
2) transformation de cette instance en rvalue reference (gr�ce � std::move)
3) appel du move constructor, et donc �change des valeurs de pointeur xmlDocPtr (NULL contre un pointeur valide)
4) destruction de la rvalue reference, qui contient un nullptr (donc le destructeur ne fait pas grand chose)
5) destruction de l'instance "d"
C'est probablement l� (dans mon esprit, je veux dire) que le b�t blesse. Parce que les choses ne se passent pas du tout comme �a. A la place, le constructeur prenant une rvalue ref n'est jamais appel�, donc l'�change ne se passe jamais, et les deux instances existantes (la temporaire et celle qui est r�ellement utilis�e) poss�dent le m�me pointeur. Bien evidemement, un probl�me se pose lors de la destruction : xmlFreeDoc() plante, lamentablement, parce que le pointeur est lib�r� deux fois.
Ce n'est pas ce qui �tait pr�vu dans mon esprit tortur�.
Est-ce que l'un de vous pourrait me pointer mon erreur - de raisonnement, de code, etc - et (bonus accord� sous la forme de mon �ternelle gratitude) m'expliquer ce que visiblement, je n'ai pas compris (et comme je ne l'ai pas compris, je ne sais m�me pas ce que c'est) ?
Merci d'avance !
Partager