2 votes

Pourquoi static ofstream ne fonctionne pas

Je développe un programme en c++ avec beaucoup d'opérations d'E/S de fichier. J'ai défini un ofstream statique dans un en-tête commun afin qu'il soit accessible partout dans le projet. La structure des codes est énumérée comme suit: toutes les variables communes sont définies dans com.h, test.h et test.cpp sont pour une classe appelée OPClass, main.cpp exécute le programme principal

COM.H:

#ifndef __CLCOM__
#define __CLCOM__
#include 
#include 
#include 

using namespace std;

static ofstream out;
static stringstream ss;

#endif

TEST.H:

#ifndef __CL__
#define __CL__
#include 
#include 
#include "com.h"

using namespace std;

class OPClass
{
  public:
   void run(void);
   void show(ostream &o) const;
};
#endif

TEST.CPP:

#include "com.h"
#include "test.h"

void OPClass::run(void)
{
  out << "Here is run()" << endl;
  show(out);
}

void OPClass::show(ostream &o) const
{
  o << "bonjour!" << endl;
}

MAIN.CPP:

#include "com.h"
#include "test.h"

void runmain(void)
{
  OPClass op;
  out.open("output.txt", ios::out | ios::trunc);
  out << endl << "L'état a changé!" << endl;
  op.run();
  if (out.is_open()) out.close();
}

int main(int argc, char* argv[])
{
  runmain();
  return  0;
}

Comme vous pouvez le constater, l'ofstream statique a été nommé out et sera appelé dans le programme principal et dans la classe. J'utilise mingw32 et je n'ai pas vu de problème lors de la compilation ou à l'exécution. Mais il semble que seule l'information dans runmain() sera écrite dans le fichier de sortie. Tout autre message écrit dans ce fichier dans la classe n'apparaît jamais dans le fichier de sortie. Pourquoi et comment puis-je écrire un flux de fichier commun pour que tout le monde dans le projet puisse y accéder? Merci.

3voto

HostileFork Points 14697

Chaque unité de compilation obtient son propre ss et out. Ainsi, il existe une instance différente d'eux vue par main.cpp que par test.cpp.

Vous n'avez vraiment pas besoin de statique ici. Pour remédier à cela, au lieu de déclarer les variables et leurs allocations dans le fichier d'en-tête, vous devez simplement les prototyper en utilisant le mot-clé extern.

#ifndef __CLCOM__
#define __CLCOM__
#include 
#include 
#include 

// Note : ne mettez pas les déclarations "using" dans les en-têtes
// utilisez plutôt les noms entièrement qualifiés à la place
extern std::ofstream out;
extern std::stringstream ss;

#endif

Où vous placez réellement vos déclarations dépend de vous, assurez-vous simplement que cela n'est fait qu'à un seul endroit. Cela pourrait être un fichier com.cpp ou vous pourriez le placer dans main.cpp si cela convient à votre projet.

std::ofstream out;
std::stringstream ss;

Noter que les variables globales comme celles-ci ne sont pas une bonne idée, de toute façon...

1voto

Brent Nash Points 6337

Déclaration préventive : Vous devriez accepter la réponse de @HostileFork.

Juste comme complément, une façon simple de montrer ce qu'il se passe est d'afficher l'adresse de out à chaque fois que vous essayez de l'utiliser.

Si vous ajoutez ces quelques déclarations :

void OPClass::run(void)
{
  cout << "Adresse de 'out' = " << &out << endl;
  out << "Voici run()" << endl;
  show(out);
}

Et :

void runmain(void)
{
  cout << "Adresse de 'out' = " << &out << endl; 
  OPClass op;
  out.open("output.txt", ios::out | ios::trunc);
  out << endl << "Changement d'état !" << endl;
  op.run();
  if (out.is_open()) out.close();
}

Vous remarquerez que les deux instructions d'impression pour out affichent deux adresses différentes. Cela devrait vous indiquer que vous obtenez en réalité deux instances de out créées en tant que deux variables distinctes. Les méthodes de votre OPClass tentent d'écrire vers un flux de sortie complètement différent. Cela a à voir avec la façon dont vous utilisez static dans un contexte global ; cela ne se comporte pas comme vous le pensez. Dans un contexte global, déclarer quelque chose comme static le lie à la portée locale du fichier dans lequel il se trouve.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X