Bonjour à tous
J'ai créé une classe template qui possède une méthode static (car je veux pouvoir l'appeler sans instancier d'objet de la classe) que je définit par spécialisation comme suit :
classe_template.h
Maintenant je souhaite créer une classe fille de MyClass<int>. Voici mon class2.h :
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 #ifndef CLASS_TEMPLATE_H #define CLASS_TEMPLATE_H template < typename T > class MyClass{ public : MyClass(T a, T b):c(a),c2(b){}; static void foo3(); protected : T c; T c2; }; template < > void MyClass<float>::foo3(){} template < > void MyClass<int>::foo3(){}
et le main.cxx se présente ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 #ifndef CLASS2_H #define CLASS2_H #include "class_template.h" class ClasseFille : public MyClass<int> { public : ClasseFille(int a, int b):MyClass<int>(a,b){}; }; #endif /* CLASS2_H */
Mon code étant gros (ceci n'étant qu'une toute petite partie du code que je développe), je compile avec cmake. Mon CMakeList.txt est on ne peut plus simple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #include "class2.h" #include "class_template.h" #include <iostream> #include <string> int main( int argc, char* argv[] ){ ClasseFille Obj(3,4); std::cout << "OK" << std::endl; }
Jusque là on a une base qui marche. Maintenant ce qui ne fonctionne pas. Maintenant je veux développer un peu ma classe fille.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 project(classe_template.out) add_executable(classe_template.out main.cxx )
Je créé donc un class2.cxx qui ne contient seulement (le but étant d'y mettre la définition de méthode ensuite) :
Dans mon CMakeList.txt, je rajoute donc le fichier class2.cxx à la liste des sources :
Code : Sélectionner tout - Visualiser dans une fenêtre à part #include "class2.h"
Sauf que là ca ne compile plus .... (crash lors de l'édition de lien)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 project(classe_template.out) add_executable(classe_template.out main.cxx class2.cxx )
Donc visiblement la définition de foo3 est en double.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 duplicate symbol __ZN7MyClassIfE4foo3Ev in: CMakeFiles/classe_template.out.dir/main.cxx.o CMakeFiles/classe_template.out.dir/class2.cxx.o duplicate symbol __ZN7MyClassIiE4foo3Ev in: CMakeFiles/classe_template.out.dir/main.cxx.o CMakeFiles/classe_template.out.dir/class2.cxx.o ld: 2 duplicate symbols for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
Mais justement je croyais que la présence de #ifndef ... #define ... permettait de parer ce genre de problème ...
Quelqu'un peut-il déjà m'expliquer pourquoi j'ai cette erreur ?
A part ne pas créer de class2.cxx et tout mettre dans le .h (qui rendrait juste mon code inbuvable), ai-je une autre solution ?
Merci pour votre aide
Edit: Précision : je compile avec cmake version 3.0.2 et Apple LLVM version 5.1 (clang-503.0.40). Mon code est en C++03.
Partager