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
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(){}
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
#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 */
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
#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;
}
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
project(classe_template.out)
 
add_executable(classe_template.out 
	main.cxx
)
Jusque là on a une base qui marche. Maintenant ce qui ne fonctionne pas. Maintenant je veux développer un peu ma classe fille.
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
1
2
3
4
5
6
project(classe_template.out)
 
add_executable(classe_template.out 
	main.cxx
	class2.cxx
)
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
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)
Donc visiblement la définition de foo3 est en double.
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.