2013-05-14 20 views
6

Ich muss eine Nummernklasse implementieren, die den Operator < < für die Ausgabe unterstützt. i einen Fehler haben: "Kennung "Ostream" ist nicht definiert" aus irgendeinem Grund obwohl ich auchBezeichner "ostream" ist undefinierter Fehler

hier die Header-Datei enthalten und versuchen:

Number.h

#ifndef NUMBER_H 
#define NUMBER_H 
#include <iostream> 
class Number{ 
public: 
//an output method (for all type inheritance from number): 
virtual void show()=0; 

//an output operator: 
friend ostream& operator << (ostream &os, const Number &f); 


}; 

#endif 

warum der Compiler ist nicht Ostream in der Friend-Funktion erkennen?

+0

Weil es wie bei allen Standard-Bibliothekstypen und -funktionen nur * kein 'ostream' gibt. Es gibt nur 'std :: ostream'. –

Antwort

11

Sie müssen vollständig den Namen ostream mit dem Namen des Namespace qualifizieren, die Klasse lebt in:

std::ostream 
// ^^^^^ 

So Ihre Betreiber Erklärung werden sollte:

friend std::ostream& operator << (std::ostream &os, const Number &f); 
//  ^^^^^      ^^^^^ 

Alternativ können Sie eine haben using Erklärung vor dem unqualifizierten Namen ostream erscheint:

using std::ostream; 

Damit können Sie den Namen ostream ohne vollständige Qualifikation schreiben, wie in Ihrer aktuellen Version des Programms.

+0

vielen Dank! kann mit Namespace std; wird entweder funktionieren? –

+3

Sie sollten 'using' nicht in den globalen Namespace eines Headers einfügen, da dies zu Namenskonflikten für andere Benutzer des Headers führen kann. –

+1

@AviadChmelnik: Es wird funktionieren, aber Mike Seymour weist darauf hin, dass es wegen der hohen Wahrscheinlichkeit der Einführung von Namenskonflikten (besonders wenn es in einem Header im globalen Namespace-Bereich eingefügt wird) als eine schlechte Programmierpraxis angesehen wird. Eher selektiv sein, wenn Sie können –

0

Andy Prowls Antwort ist großartig, aber bitte widersetzen sich, "std :: ostream" in eine Kopfzeile zu setzen. Wenn Sie dies tun, dann wird auch bei anderen Kompilierungseinheiten, die Ihre Header-Datei verwenden, dieser Namespace standardmäßig verwendet, und Sie können böse Kompilierungsfehler mit Namespace-Konflikten bekommen.

+2

'using std :: ostream' setzt einen Namen in den Namespace, wo es verwendet wird: 'ostream'. Das ist bei weitem kein so großes Problem wie 'using namespace std;', das ** jeden ** Namen von 'std' in diesen Namespace schreibt. –

+1

Andere Kompilierungseinheiten erhalten nur den Namen 'ostream', nicht den Namespace. Dennoch stimme ich zu, dass es eine schlechte Idee ist. – juanchopanza