0

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

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

这是我所拥有的一个例子:

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 吗?

4

2 回答 2

1

在您的示例class A中,只需打开文件并写入它,我们称之为FileWriter. class B然后你还有两个类:它们都创建了这个( )class 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);
      //...
   }

这是明显的设计错误,因为这不是组合而是聚合,换句话说:这不是“拥有”关系,这是“使用”关系。你应该做的是:

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

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

于 2014-03-22T14:49:27.513 回答
1

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

它被移动了。从参考

4) 移动构造函数。首先,从 other 移动构造基类(不影响 rdbuf() 指针),然后移动构造 std::basic_filebuf 成员,然后调用 this->set_rdbuf() 将新的 basic_filebuf 安装为 rdbuf( ) 基类中的指针。


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

见第 1 点。

你会建议我在每个析构函数中添加 oFile.close() 函数吗?

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

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

无法说出上述答案对您的用例有什么影响。

于 2014-03-22T14:51:46.660 回答