Question

Je veux dire, je tentais de surcharger l'opérateur << intérieur de la classe

comme ceci

 class A {
      public:
           ostream &operator<<(ostream &os);// which doesnt work

      private:
           friend ostream &operator<<(ostream &os, const A& a); //Works
           int i;

 };

  Definition
          ostream &operator<<(ostream &os, const A& a) {
              os<<a.i;
              return os;
          }

pourquoi je ne peux pas surcharger l'opérateur à l'intérieur de la classe spécifique à la classe? ou Am quelque chose que je manque? ou suis-je stupide de penser même façon un tel? S'il vous plaît conseiller.

Était-ce utile?

La solution

La fonction de membre:

ostream &operator<<(ostream &os);

fait le travail, mais pas pour la situation que vous voulez. Elle sera appelée quand vous faites quelque chose comme:

A a;
a << std::cout;

i.e.. où l'objet est du côté gauche de l'opérateur.

Autres conseils

Le problème est que votre operator<< prendrait ostream comme second paramètre, et non pas une première. De cette façon, vous pouvez faire myObject << std::cout, mais il regarderait unintuitive et vous ne seriez pas en mesure d'enchaîner les appels en raison de operator<< étant laissé associatif.

Un autre avantage de déclarer l'opérateur comme un ami par opposition à une fonction membre est que les conversions automatiques peuvent se produire. Cela signifie que si vous avez un B de classe qui ne dérive pas de A mais a un constructeur de B(A const&), vous serez toujours en mesure de le faire std::cout << my_b; et l'ont converti en un A puis imprimé.

Heureusement, la définition operator<< comme un ami peut se faire dans la classe si vous préférez. Votre code pourrait être écrit comme

class A {
    int i;
    friend std::ostream& operator<<(std::ostream& o, A const& a) {
        o << a.i;
        return o;
    }
};

Pourquoi ne pas la norme pour vous permettre de spécifier de quel côté l'argument devrait continuer? Feignons il l'a fait, et ajouter les mots-clés left_of et right_of préciser:

struct B;

struct A {
     A left_of operator+(B const&) {
         return *this;
     }
};

struct B {
     B right_of operator+(A const&) {
         return *this;
     }
};

Qu'est-ce qui se passe maintenant, quand nous faisons A a; B b; f(a + b);? Chaque classe a un opérateur qui gère ce cas, ce qui signifie que nous ne pouvons pas décider. Car de nombreux opérateurs devraient être des amis en raison des possibilités de conversion de toute façon, ne pas laisser ce genre de chose n'est pas un grand problème, et empêche ce genre d'ambiguïtés. (Bien sûr, vous pouvez également définir un opérateur membre et un libre, ce qui causerait un problème très similaire.)

Par ailleurs, comme les choses sont, la définition de votre friend operator<< est rien de retour, ce qui gâchera enchaînant.

Rappelez-vous que pour une fonction membre non statique d'une classe premier argument est ce pointeur. Ainsi, la signature de votre fonction « opérateur << », après la compilation deviendra:

ostream &operator<<(A *this, ostream &os);

Cela fonctionne quand vous faites quelque chose comme:

A obj;
obj << std::cout;

Pensez à "obj" comme premier argument et "std :: Cout" comme 2ème argument de l'opérateur "<<".

Une meilleure façon de surcharge « << » est en utilisant la fonction ami, car de cette façon vous pouvez faire votre associative de l'opérateur surchargée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top