我遇到了一个有趣的案例:
我有一个文件流作为类的成员,以及一个在文件中写入数据的函数。该对象作为参数传递给另一个使用该参数初始化其成员的类。因此我遇到了一些问题,我设法用字符串向量并在其中添加行来解决它们。但现在我发现我仍然将对象从一个类传递到另一个类。
以下是我的例子:
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吗?
答案 0 :(得分:1)
在您的示例class A
中,只需打开文件并写入文件,我们就将其称为FileWriter
。然后,您还有两个类:class B
和class C
,即使他们不必,也会创建此FileWriter
(A
)的副本:
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吗?
无法说明上述答案对您的用例有何影响。