2017-08-02 9 views
0

Ich versuche, neu erstellten Knoten mit Dereferenzierungsoperator zu drucken.C++: Zugriff auf Knotenwert nicht möglich

Meine Hauptfunktion

int main() 
{ 
    Insert(3); 
    return 0; 
} 

Insert() Funktion

void Insert(int data) 
{ 
    Node *temp = new Node ; 
    temp -> data = data ; 
    temp -> next = NULL ; 

    cout << *temp ; 

} 

Mein Fehler:

tp.cpp: In function ‘void Insert(int)’: 
tp.cpp:27:10: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘Node’) 
    cout << *temp ; 
+1

Es gibt keine '<<' Überladung für 'Node' in der Standardbibliothek. Du leckst auch 'Node * temp = new Node;' – user4581301

+0

Dann, wie Knotenwert dann zu sehen, dass ich gerade erklärt habe? Danke! –

+1

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

Antwort

1

Problem: C++ zur Verfügung stellen s Operatoren nur für die Grundtypen, für benutzerdefinierte Typen müssen wir einen eigenen Operator schreiben. Der Fehler no match for ‘operator<<’ sagt, dass der Compiler keinen << Betreiber gegen die Aussage cout << *temp ;

Mögliche Lösungen finden konnten:

  1. Wie @ user4581301 sagte, Sie können write your own operator von << für Ihre Art Node.

  2. Sie können die cout << *temp ;-Anweisung auch durch cout << temp->data ; oder cout << (*temp).data ; ersetzen, da temp der Zeiger auf eine Struktur ist. Sie können entweder mit -> vor dem data oder mit einem . auf es zugreifen, aber nach der Dereferenzierung mit dem Operator *.

0

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 :)

Verwandte Themen