Pergunta

I met an interesting case:

I have a file stream as a member of a class, and a function that writes data in the file. The object is passed as parameters to another class that initializes its member with the parameter. I had some problems because of this and I have managed to solve them with a vector of strings and adding rows into it. But now I figure out that I still pass the object from one class to another.

Here is an example of what I have:

class A
{
private:
   std::ofstream oFile;
   std::vector<std::string> oFileStringVec;
public:
   A()
   {
      oFile.open("../Path/File.txt", std::fstream::out);
      if (!oFile.is_open()) { std::cout<<"Error!!\n";}
   }
   ~A() {}

   void writeInfo(const std::string& s) 
   { oFileStringVec.push_back(s); }

   void closeFile()
   { oFile.close(); }
};

class B
{
private:
   A ma;
public:
   B(const A& aOb) : ma(aOb) {}

   void foo() 
   {
      // ...
      ma.writeInfo(mystr);
   }
   // ...
};

class C
{
private:
   A ma;
public:
   C(const A& aOb) : ma(aOb) {}
   // ...
   void foo()
   {
      // ...
      B myB(myA);
      //...
   }
};

And I have a function where I create a C object and call it's foo() method:

void bar()
{
   // ...
   A myA;
   // ...
   C myC(myA);
   myC.foo();
   //...
}

I am not really sure what is going on here. Is the ofstream created more than once? It is created only once and then it is just re-opened? Would you qdvice me to add in every destructor the oFile.close() function? Shall I pass as parameter just the vector and use the ofstream just in the bar() function?

Foi útil?

Solução

I am not really sure what is going on here. Is the ofstream created more than once?

It's moved. As from the reference:

4) Move constructor. First, move-constructs the base class from other (which does not affect the rdbuf() pointer), then move-constructs the std::basic_filebuf member, then calls this->set_rdbuf() to install the new basic_filebuf as the rdbuf() pointer in the base class.


It is created only once and then it is just re-opened?

See 1st point.

Would you qdvice me to add in every destructor the oFile.close() function?

That's already done in the std::ofstream destructor automatically

Shall I pass as parameter just the vector and use the ofstream just in the bar() function?

Can't tell what the above answers have as consequences for your use case.

Outras dicas

In your example class A just opens file and writes to it, let's call it FileWriter. Then you have two more classes: class B and class C that both create a copy of this FileWriter (A) even when they don't have to:

class B
{
private:
   A ma;
public:
   B(const A& aOb) : ma(aOb) {}

and

class C
{
private:
   A ma;
public:
   C(const A& aOb) : ma(aOb) {}
   // ...
   void foo()
   {
      // ...
      B myB(myA);
      //...
   }

This is obvious design error since this was not meant to be composition but an aggregation, in other words: this is not "has" relationship, this is "uses" relationship. What you should do is:

class B
{
private:
    const A& a_;
public:
    CBar(const A& a) : a_(a) {...}
};

or if A is trully meant to be copy-able and your intent is to copy it, then it should not hold std::ofstream object but rather a reference to it.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top