Jeder Operator ist im Grunde eine Funktionen. ein Additionsoperator überladener Operator + für Ihre Klasse Zum Beispiel Rational könnte als Member-Funktion ausgedrückt werden:
class Rational
{
private:
...
...
public:
...
//Implicit arg "this" is Left Hand operand.
//Explicitly stated arg objRational is Right Hand operand.
Rational operator+(const Rational& objRational) const {...};
...
};
Bitte beachten Sie, dass das Argument gemacht const
hier, um sicherzustellen, dass wir die Operanden ändern sich nicht versehentlich und auch die Funktion markiert sich selbst const
, um sicherzustellen, dass wir this
Objekt nicht ändern. Arg wird durch ref übergeben, weil, wenn wir es nicht sicher ändern, keine Notwendigkeit zu kopieren und kein Schaden in ref.
Die oben ist technisch eine Funktion, so dass Sie so etwas wie
Rational r1(3, 4), r2(22, 7);
Rational r3 = r1.operator+(r2); //Really possible! Try it!
tun können Es ist dann nur ein syntaktischer Zucker hinzugefügt, um C++ Grammatik des gleichen Anruf wie
Rational r3 = r1 + r2;
zu ermöglichen
Sie haben
geschrieben
cout << *temp ;
Davon Art von (*temp)
Knoten ist, und cout
ist ein Ziel der ostream
Klasse.
So sucht der Compiler nun nach einem überladenen Operator mit linkem Operanden und einem ostream
Objekt und einem rechten Operanden ein Node
Objekt.
Also, es ist so gut wie Schreiben, irgendwo in der Klasse ostream selbst
class ostream : ...
{
...
...
//Here, the only one explicit arg is Node,
//which is Right Hand side operand.
//Since it is a member operator,
//implicit arg "this" will be, by default, the LH operand.
public ostream& oprtator<<(const Node& objNode){...}
...
}
Aber wir haben nicht diese Möglichkeit, da wir nicht Klasse ostream in erster Linie geschrieben haben. Und als es geschrieben wurde, existierte dein Knoten nicht! Außerdem muss möglicherweise auf private Mitglieder von objNode zugegriffen werden, die für eine Funktion, die kein Mitglied der Node-Klasse ist, nicht erlaubt sind.
Wenn wir versuchen, es als Mitglied des Klassenknotens zu setzen, kann es auf die privaten Mitglieder des Knotens zugreifen. Aber jetzt muss der linke Operand der operator<<
Knoten sein, was den ganzen Zweck ruiniert.
Also, was wir tun, macht es zu einem Freund Funktion.
class Node
{
...
...
public:
...
//Since this is NOT a member, bot LH and RH operand need to be stated explicitelty
friend ostream& operator<< (ostream& out, const Node& objNode) { out << node.data; return out; }
...
};
Dies schafft eine operator<<
die Operanden verlassen hat ein ostream
und rechten Operanden ein node
, und die privaten Mitglieder der Knoten zugreifen können, weil es Freund ist. (^_^)
Warum akzeptieren Sie und geben Sie Referenz von Ostream Objekt zurück?
Wenn Sie versuchen, die Aufrufe zu verketten, müssen Sie das gleiche Objekt seriell in geschrieben erhalten.
Betrachten Sie eine Erklärung ab: cout << "First: " << objNode1 << ", Second: " << objNode2;
Es wird von innen nach außen, für jeden Anruf als
(
(
(
cout << "First: " //Innermost call
) << objNode1
) << ", Second: "
)<< objNode2;
ausgewertet werden, müssen wir die ostream
Objekte an den überladenen Operator übergeben werden, das die vorherig alle hat Einfügungen und daher die inneren Aufrufe müssen den Verweis auf das geänderte (nach dem Einfügen) Objekt ostream
zurückgeben.
Ich hoffe, es hilft; Happy Coding :)
Es gibt keine '<<' Überladung für 'Node' in der Standardbibliothek. Du leckst auch 'Node * temp = new Node;' – user4581301
Dann, wie Knotenwert dann zu sehen, dass ich gerade erklärt habe? Danke! –
Sie müssen Ihren eigenen Operator '<<' schreiben, um 'Node' zu behandeln. Schlagen Sie hier die Stream (Bitshift) Operatoren auf: https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-andidioms-for-operator-overloading – user4581301