复制构造函数是否重新初始化文件成员

时间:2014-03-22 14:35:48

标签: c++ default-copy-constructor

我遇到了一个有趣的案例:

我有一个文件流作为类的成员,以及一个在文件中写入数据的函数。该对象作为参数传递给另一个使用该参数初始化其成员的类。因此我遇到了一些问题,我设法用字符串向量并在其中添加行来解决它们。但现在我发现我仍然将对象从一个类传递到另一个类。

以下是我的例子:

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);
      //...
   }
};

我有一个函数,我在其中创建一个C对象并调用它的foo()方法:

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

我不确定这里发生了什么。是不是一次创造了ofstream?它只创建一次然后重新打开?您是否可以在每个析构函数中添加oFile.close()函数?我应该仅仅作为参数传递向量,并在bar()函数中使用ofstream吗?

2 个答案:

答案 0 :(得分:1)

在您的示例class A中,只需打开文件并写入文件,我们就将其称为FileWriter。然后,您还有两个类:class Bclass C,即使他们不必,也会创建此FileWriterA)的副本:

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

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

这是显而易见的设计错误,因为这不是组合而是聚合,换句话说:这不是&#34;有&#34;关系,这是&#34;使用&#34;关系。你应该做的是:

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

或者如果A完全意图是可复制的,并且您的意图是复制它,那么它不应该包含std::ofstream个对象,而应该是对它的引用。

答案 1 :(得分:1)

  

我不确定这里发生了什么。是不是一次创造了ofstream?

它感动了。从reference开始:

  

4)移动构造函数。首先,move-从其他构造基类(不影响rdbuf()指针),然后移动构造std :: basic_filebuf成员,然后调用this-&gt; set_rdbuf()来安装新的basic_filebuf作为rdbuf ()指针在基类中。


  

它只创建一次,然后才重新打开?

见第1点。

  

请问我在每个析构函数中添加oFile.close()函数吗?

已经在std::ofstream析构函数中自动完成了

  

我应该只将矢量作为参数传递,并在bar()函数中使用ofstream吗?

无法说明上述答案对您的用例有何影响。