2009-07-01 5 views
0

Je trouve cette fonction dans le fichier d'en-tête d'une classe abstraite:Comment implémenter 'virtual ostream & print (ostream & out) const;'

virtual ostream & print(ostream & out) const; 

Quelqu'un peut-il me dire quel genre de fonction ce qui est et comment déclarer dans une classe dérivée? De ce que je peux dire, il semble que cela renvoie une référence à un courant.

Si je mets en œuvre dans mon dossier cc avec rien, je reçois une erreur de compilation:

error: expected constructor, destructor, or type conversion before ‘&’ token

que quelqu'un peut me montrer une implémentation simple de comment l'utiliser?

Répondre

1

une mise en œuvre:

ostream& ClassA::print(ostream& out) const 
{ 
    out << myMember1 << myMember2; 
    return out; 
} 

De retour le même ostream permet des combinaisons comme

a.print(myStream) << someOtherVariables; 

Cependant, il est toujours étrange de l'utiliser de cette façon.

En ce qui concerne l'erreur, ostream fait partie de l'espace de noms std, et ne fait pas partie de l'espace de noms global ou l'espace de noms de la classe vous fait partie se référant.

1
#include <iostream> 
using namespace std; 

struct A { 
    virtual ostream & print(ostream & out) const { 
     return out << "A"; 
    } 
}; 

Il est courant de faire une fonction d'impression virtuelle, car l'opérateur < < couramment utilisé pour la sortie de flux ne peut pas être ainsi (parce que ce n'est pas une fonction de membre).

2

Vous avez probablement oublié d'inclure iostream ce qui rend ostream visible. Vous devez également modifier cela en std::ostream, car les noms de bibliothèque standard C++ se trouvent dans l'espace de noms std.

Do not write using namespace std; in a header-file, ever!

Il est bon de le placer dans le fichier de mise en œuvre, si vous voulez, ou si vous écrivez un exemple pour un ami. Parce que tout fichier qui inclut cet entête aura toute la bibliothèque standard visible sous forme de noms globaux, ce qui est un gros gâchis et sent beaucoup. Il augmente soudainement la chance de conflits de noms avec d'autres noms globaux ou d'autres noms - je ne voudrais pas utiliser de directives du tout (voir Using me par Herb Sutter). Donc, changer le code dans celui-ci

#include <iostream> 
// let ScaryDream be the interface 
class HereBeDragons : public ScaryDream { 
    ... 
    // mentioning virtual in the derived class again is not 
    // strictly necessary, but is a good thing to do (documentary) 
    virtual std::ostream & print(std::ostream & out) const; 
    ... 
}; 

Et dans le fichier de mise en œuvre (".cpp")

#include "HereBeDragons.h" 

// if you want, you could add "using namespace std;" here 
std::ostream & HereBeDragons::print(std::ostream & out) const { 
    return out << "flying animals" << std::endl; 
} 
+0

+1 pour les noms de classe descriptive :) – Eric

Questions connexes