web-dev-qa-db-fra.com

c ++ définitions multiples de l'opérateur <<

J'essaie de remplacer l'opérateur << Pour une classe. Le but est essentiellement d'implémenter un comportement similaire à toString() pour ma classe, de sorte que son envoi à cout produira une sortie utile. En utilisant un exemple factice, j'ai le code ci-dessous. Lorsque j'essaie de compiler, j'obtiens l'erreur suivante:

$ g++ main.cpp Rectangle.cpp
/tmp/ccWs2n6V.o: In function `operator<<(std::basic_ostream<char, std::char_traits<char> >&, CRectangle const&)':
Rectangle.cpp:(.text+0x0): multiple definition of `operator<<(std::basic_ostream<char, std::char_traits<char> >&, CRectangle const&)'
/tmp/ccLU2LLE.o:main.cpp:(.text+0x0): first defined here

Je ne peux pas comprendre pourquoi cela se produit. mon code est ci-dessous:

Rectangle.h:

#include <iostream>
using namespace std;

class CRectangle {
    private:
        int x, y;
        friend ostream& operator<<(ostream& out, const CRectangle& r);
    public:
        void set_values (int,int);
        int area ();
};

ostream& operator<<(ostream& out, const CRectangle& r){
    return out << "Rectangle: " << r.x << ", " << r.y;
}

Rectangle.cpp:

#include "Rectangle.h"

using namespace std;

int CRectangle::area (){
    return x*y;
}

void CRectangle::set_values (int a, int b) {
    x = a;
    y = b;
}

main.cpp:

#include <iostream>
#include "Rectangle.h"

using namespace std;

int main () {
    CRectangle rect;
    rect.set_values (3,4);
    cout << "area: " << rect.area();
    return 0;
}
30
ewok

Vous enfreignez la règle d'une définition. Une solution rapide est:

inline ostream& operator<<(ostream& out, const CRectangle& r){
    return out << "Rectangle: " << r.x << ", " << r.y;
}

D'autres sont:

  • déclarer l'opérateur dans le fichier d'en-tête et déplacer l'implémentation vers Rectangle.cpp fichier.
  • définir l'opérateur à l'intérieur de la définition de classe.

.

class CRectangle {
    private:
        int x, y;
    public:
        void set_values (int,int);
        int area ();
        friend ostream& operator<<(ostream& out, const CRectangle& r){
          return out << "Rectangle: " << r.x << ", " << r.y;
        }
};

Prime:

  • utiliser des gardes
  • retirer le using namespace std; de l'en-tête.
42
Luchian Grigore

Vous placez la définition d'une fonction dans un .h fichier, ce qui signifie qu'il apparaîtra dans chaque unité de traduction, en violation de la règle de définition unique (=> vous avez défini operator<< dans chaque module objet, donc l'éditeur de liens ne sait pas lequel est "le bon").

Tu peux soit:

  • écrivez juste la déclaration de votre opérateur (c'est-à-dire son prototype) dans le fichier .h et déplacez sa définition dans rectangle.cpp
  • faire operator<<inline - inline les fonctions peuvent être définies plusieurs fois, tant que toutes les définitions sont identiques.

(De plus, vous devez utiliser des protège-têtes dans vos inclusions.)

15
Matteo Italia