2017-05-18 8 views
-2

Ich benutze C++.Aufruf zum übergeordneten Operator << C++

Ich versuche opeator < < wie folgt außer Kraft zu setzen (H-Datei):

friend ostream& operator<<(std::ostream& os, const Worker& obj); 

cav:

ostream & operator<<(std::ostream & os, const Worker & obj) 
{ 
    return os << "First Name: " << obj.GetFirstName() << ", Last Name: " << obj.GetLastName() << " ,ID: " << obj.GetID() << ", WorkPlace: " << obj._workPlace << endl; 
} 

Verwendung:

Person *w2 = new Worker("First Name", "Last Name", "123456789", "String"); 

cout << w2; 

Aber der Betreiber < < Wird nicht angerufen.

Was ist der Fehler?

Danke !.

+2

Sie wollen 'cout << * w2;'. – songyuanyao

+0

Sie liefern 'Person *' anstelle von 'Person'. –

+1

Vermeiden Sie Zeiger und 'neue'. –

Antwort

0

Ihre std::cout << w2; statt std::cout << *w2; Fehler das größere Problem versteckt hat: Sie versuchen, Polymorphismus zu verwenden, indemzwingende(Aufruf zum übergeordneten Operator < <), dies ist jedoch kein Überschreiben, sondern Überladen, daher wird friend ostream& operator<<(std::ostream& os, const Worker& obj) nicht für Person aufgerufen, auch wenn der Zeiger Person tatsächlich auf ein Objekt Worker zeigt.

Die Polymorphismus-Lösung soll operator<< für die Basisklasse überladen, die eine virtuelle Funktion aufruft, die von einer abgeleiteten Klasse überschrieben werden kann.

struct Base 
{ 
    virtual std::string toString() { return "Base"; } 
} 

struct Derived: Base 
{ 
    virtual std::string toString() { return "Derived"; } 
} 

ostream & operator<<(std::ostream & os, const Base & obj) 
{ 
    return os << obj.toString() << endl; 
} 
1

w2 ist ein Zeiger auf ein Person Objekt, während Ihre operator<< eine const-Referenz erwartet. Sie können entweder einen anderen << Operator schreiben, die eine Person* oder verwenden Sie nimmt

cout << *w2; 
0

Aber die operator<< wird nicht aufgerufen.

Was ist der Fehler?

Da übergeben Sie einen Zeiger (z. B. eine Adresse) und das ist, was Sie in Ihrer Ausgabe erhalten werden.

Da Sie operator<< für eine Worker haben, haben Sie es auf diese Weise zu tun:

Worker *w2 = new Worker("First Name", "Last Name", "123456789", "String"); 
cout << *w2; 

oder, Sie Person-Worker zurückgeworfen, wenn Sie sicher sind, dass das eigentliche Objekt ist ein Worker:

Person *w2 = new Worker("First Name", "Last Name", "123456789", "String"); 
cout << *(Worker*)w2; 
0

Dies ist nicht überschreiben; Sie überschreiben virtuelle Mitgliedsfunktionen. Dies ist überladen und welche Funktion zum Aufrufen wird aus dem Typ der Variablen zum Zeitpunkt der Kompilierung, nicht vom Typ des Objekts zur Laufzeit bestimmt.

unter der Annahme, so dass Worker erbt von Person, auch *w2 verwendet, wird nicht funktionieren, da diese eine Person& und kein Worker& ist.

Fügen Sie in der Basisklasse eine virtuelle Ausgabefunktion hinzu, überschreiben Sie diese und ersetzen Sie den übergeordneten Operator durch einen Operator, der diese Funktion nur aufruft.

class Person 
{ 
    public: 
    // ... 
     virtual void write(std::ostream& os); 
    }; 

std::ostream& operator<<(std::ostream& os, const Person& p) 
{ 
    p.write(os); 
    return os; 
} 

class Worker : public Person 
{ 
    public: 
    // ... 
     void write(std::ostream& os) override; 
}; 

Sie benötigen keinen anderen Operator als den für die Basisklasse.