IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Surcharge d'opérateur : erreur de linkage


Sujet :

C++

  1. #1
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 64
    Points : 170
    Points
    170
    Par défaut Surcharge d'opérateur : erreur de linkage
    Bonjour,

    Je suis en train d'écrire une classe de gestion de grands entiers, et j'aimerais redéfinir les opérateurs de base.

    Seulement voilà, j'ai une erreur de linkage que je n'arrive pas à résoudre (ou pas comme je veux en tout cas).

    voici le code de ma classe :

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    #ifndef BIGINT_H
    #define BIGINT_H
     
    #include <iostream>
    #include <string>
     
    using namespace std;
     
    namespace RSAPTut {
     
    	class BigInteger {
    	private:
    		int size;	// le nombre de chiffres
    		int sign;	// -1 si <0, 0 sinon
    		unsigned short * number;	// chiffres du moins significatif au plus significatif
     
    	public:
    		// Constructeurs
    		BigInteger();
    		BigInteger(BigInteger * big);
     
     
    		// Getters
    		inline int getSign() { return this->sign;	}
    		inline int getSize() { return this->size;	}
    		unsigned short * getNumber() {	return this->number;	}
     
    		// Setters
    		inline void setSign(int sign) {	this->sign=sign;	}
    		inline void setSize(int size) {	this->size=size;	}
    		inline void setNumber(unsigned short * number, int size) {
    			this->size = size;
    			this->number = new unsigned short[size];	// on alloue la mémoire pour number
    			for (int i=0; i<size; i++)
    				this->number[i] = number[i];	// on recopie la valeur dans number
    		}
     
    		// Utilitaires
    		void print();
    		void stringToBigInteger(char * s);
    		void setDigit(unsigned short d);
     
    	};
     
     
     
    	// Méthodes primitives
    	[...]
     
    	// Opérations de base
    	BigInteger add(BigInteger M, BigInteger N);	// Addition
    	[...]
     
    	// Opérations modulaires
    	[...]
     
    	// Opérateurs
    	BigInteger operator+(const BigInteger &m, const BigInteger &n)	{
    		BigInteger r = new BigInteger( add(m,n) );
     
    		return r;
    	}
     
    };
     
    #endif
    j'ai défini mon opérateur + en dehors de ma classe mais dans un namespace.

    En plus de ce code j'ai :
    • l'implémentation dans un fichier séparé, qui inclus ce .h et où toutes les méthodes sont implémentées dans le namespace
    • un fichier main pour tester


    Si je compile tel quel, j'obtiens le message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Compiling...
    main.cpp
    BigInteger.cpp
    Linking...
    main.obj : error LNK2005: "class RSAPTut::BigInteger __cdecl RSAPTut::operator+(class RSAPTut::BigInteger const &,class RSAPTut::BigInteger const &)" (??HRSAPTut@@YA?AVBigInteger@0@ABV10@0@Z) already defined in BigInteger.obj
    main.obj : error LNK2005: "class RSAPTut::BigInteger __cdecl RSAPTut::operator+(class RSAPTut::BigInteger const &,class RSAPTut::BigInteger const &)" (??HRSAPTut@@YA?AVBigInteger@0@ABV10@0@Z) already defined in BigInteger.obj
    Debug/RSA.exe : fatal error LNK1169: one or more multiply defined symbols found
    Error executing link.exe.
     
    RSA.exe - 3 error(s), 0 warning(s)

    J'arrive à faire fonctionner l'opérateur en le définissant dans le fichier ou se trouve le main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // Opérateurs
    RSAPTut::BigInteger operator+(const RSAPTut::BigInteger &m, const RSAPTut::BigInteger &n)	{
    	RSAPTut::BigInteger r = new RSAPTut::BigInteger( RSAPTut::add(m,n) );
     
    		return r;
    	}
     
    int main()
    {
    [...]
    }
    Voilà donc je ne sais pas comment résoudre ce problème (je ne souhaite pas mettre tous les opérateurs dans le main.cpp), donc si quelqu'un sait comment faire ?
    merci.

  2. #2
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Tu définis des fonctions non inline dans un en-tête. L'en-tête devrait se contenter de les déclarer.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  3. #3
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Ca a l'air louche ce que tu fais dans ton opérateur +. Tu assignes à un objet un pointeur vers un autre ?? Pas correct, ça. Pourquoi ne pas retourner directement add(m, n) ?

    Bon, ensuite, pour ton opérateur, tu devrais faire comme pour add, ne déclarer que le prototype et mettre le corps de la fonction dans un autre fichier .cpp, genre BigInteger.cpp.

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    C'est normal, la définition de operator+ est dans le .h, ce qui fait qu'il est compilé plusieurs fois.

    La solution est soit de mettre son code dans le .cpp soit d'utiliser inline.

  5. #5
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par Sylvain Togni
    La solution est soit de mettre son code dans le .cpp soit d'utiliser inline.
    Sachant qu'inline n'est qu'une proposition, pas une obligation que le compilateur doit suivre.

  6. #6
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 64
    Points : 170
    Points
    170
    Par défaut
    merci

    j'ai corrigé pour le setNumber, et la bidouille dans le operator+ en fait ca venait d'une petite erreur que j'avais avant qui faisait que j'avais du bidouiller. je l'ai mis en inline :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	inline BigInteger operator+(const BigInteger &m, const BigInteger &n) {	return add(m,n);	}
    et ça marche nickel !

    merci à vous.

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par Miles
    Sachant qu'inline n'est qu'une proposition, pas une obligation que le compilateur doit suivre.
    Ça dépend, inline a deux sens :
    - Générer le code de la fonction en-ligne,
    - Permettre à une fonction d'être définie dans plusieurs unités de compilation.
    Le premier n'est pas une obligation, en effet. Le second, si.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/10/2009, 20h49
  2. Erreur lors de surcharge d'opérateur
    Par Dani3L dans le forum C++
    Réponses: 9
    Dernier message: 18/09/2008, 20h12
  3. [C#] Tri d'objet et surcharge d'opérateur
    Par Royd938 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 17/12/2007, 00h26
  4. surcharge opérateur erreur compilation
    Par damien77 dans le forum C++
    Réponses: 8
    Dernier message: 21/02/2007, 17h59
  5. [VB .NET] Surcharge d'opérateur
    Par Franckintosh dans le forum VB.NET
    Réponses: 2
    Dernier message: 07/09/2004, 19h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo