Frage

Ich meine, ich habe versucht, den Operator << in der Klasse zu überladen

so was

 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;
          }

Warum kann ich den Operator nicht in der Klasse, die für die Klasse spezifisch ist, überlasten? Oder vermisst ich etwas? Oder bin ich dumm, überhaupt so zu denken? Bitte beraten.

War es hilfreich?

Lösung

Die Mitgliedsfunktion:

ostream &operator<<(ostream &os);

tut Arbeit, aber nicht für die Situation, die Sie wollen. Es wird aufgerufen, wenn Sie so etwas tun wie:

A a;
a << std::cout;

dh wo das Objekt die linke Seite des Bedieners ist.

Andere Tipps

Das Problem ist, dass Ihre operator<< würde nehmen ostream Als zweiter Parameter nicht als erster. Auf diese Weise könnten Sie tun myObject << std::cout, aber es würde unintuitiv aussehen und Sie würden keine Anrufe anketten können operator<< links zu assoziativ sein.

Ein weiterer Vorteil der Erklärung des Bedieners als Freund im Gegensatz zu einer Mitgliedsfunktion besteht darin, dass automatische Konvertierungen auftreten können. Das heißt, wenn Sie eine Klasse haben B das leitet sich nicht aus A hat aber eine B(A const&) Konstruktor können Sie noch tun std::cout << my_b; und lassen es zu einem konvertiert A und dann gedruckt.

Zum Glück definieren operator<< Als Freund kann innerhalb der Klasse erledigt werden, wenn Sie es vorziehen. Ihr Code könnte geschrieben werden als

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

Warum erlaubt der Standard nicht, dass Sie angeben, auf welcher Seite das Argument stattfinden soll? Stellen wir uns so aus, left_of und right_of Schlüsselwörter, um anzugeben:

struct B;

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

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

Was passiert jetzt, wenn wir es tun? A a; B b; f(a + b);? Jede Klasse hat einen Bediener, der diesen Fall behandelt, was bedeutet, dass wir uns nicht entscheiden können. Da viele Betreiber aufgrund der Konversionsmöglichkeiten ohnehin Freunde sein sollten, ist es kein großes Problem, so etwas zuzulassen, und verhindert diese Art von Unklarheiten. (Natürlich können Sie auch einen und ein kostenlosen Mitgliedsbetreiber definieren, was ein sehr ähnliches Problem verursachen würde.)

Übrigens wie die Dinge die Definition Ihrer friend operator<< Nicht zurückzugeben, was die Verkettung durcheinander bringt.

Denken Sie daran, dass für eine nicht statische Mitgliedsfunktion eines ersten Arguments dieser Zeiger ist. Die Signatur Ihrer Funktion "Operator <<" nach der Zusammenstellung wird also:

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

Dies wird funktionieren, wenn Sie so etwas tun:

A obj;
obj << std::cout;

Stellen Sie sich "Obj" als erstes Argument und "std :: cout" als 2. Argument für den Operator "<<" vor.

Bessere Möglichkeit, "<<" zu überlasten, besteht darin, die Freundschaftsfunktion zu verwenden, da Sie auf diese Weise Ihren überlasteten Operator assoziativ machen können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top