【发布时间】:2018-10-24 19:09:59
【问题描述】:
我一直在开发一个个人词典应用程序,它可以帮助您记住所学的单词。它是通过 CLI 操作的(不要质疑这一点,这只是一个测试,我对 CLI 应用程序有一种奇怪的热情)。所以,我当然使用ostreams 在 CLI 上编写信息。我习惯为每个类编写operator<< 重载(用于ostreams),这样我就可以建立一个多级输出系统(基本上每个对象都可以为自己“说话”)。
为了持久化一个字典对象,我想使用ofstream 并用它写一个文件。当然,我也为ofstream 编写了operator<< 重载,并采用相同的“分层”结构。
因此,我现在在每个类中都有两个 operator<< 重载,例如“Dictionary”:
ostream& operator<<(ostream&, const Dictionary&);
ofstream& operator<<(ofstream&, const Dictionary&);
(这只是头文件中的声明)
请注意,这两个重载不同的事情非常重要。我不想在 CLI 上有一些奇怪的面向持久性的特殊格式文本而且我的文件中也不是用户友好的纯文本。
问题在于,由于ostream 和ofstream 的继承结构,ofstream 有时会隐式转换为ostream。当这种情况发生在我的 file 输出操作堆栈中间时,程序会突然跳入错误的重载并在文件中打印纯文本。
我的问题很简单:有没有办法避免或恢复这些不需要的隐式转换,以便让我的程序跳转到正确的重载?或者有没有其他好的方法来解决这个问题?
编辑 1:
有人在 cmets 中指出,这不是隐含的转换。 ofstream 有时被“视为”它的基类 ostream。问题是在某些时候对象“忘记”它是ofstream 并丢失所有与文件相关的信息。从那里开始,它只是一个ostream,这就是我所说的“转换”。
编辑 2:
可以在此处找到程序中发生“不需要的转换”的确切点:
ofstream& operator<<(ofstream& of, const Section& s) {
return s.print_ofstream(of);
}
所以这个运算符重载调用“print_ofstream”:
ofstream& Section::print_ofstream(ofstream& of) const {
of << "sec" << Util::ID_TO_STRING(section_id) << ":\n";
for (pair<Wordlist, Wordlist> pwl : translations) {
of << '{' << pwl.first << '=' << pwl.second << "}\n";
}
of << "#\n";
return of;
}
注意“pwl”是一对两个Wordlists,因此pwl.first / pwl.second 是Wordlist。因此,通常of << '{' << pwl.first << '=' << pwl.second << "}\n"; 行应该调用Wordlist 中的ofstream operator<< 重载。但事实并非如此。而是调用另一个重载方法:
ostream& operator<<(ostream& o, const Wordlist& wl) {
return wl.print_ostream(o);
}
【问题讨论】:
-
不是
ofstream被隐式转换,而是ostream是ofstream的基类。 -
确实如此,但我有点困惑,返回类型为ofstream的方法可以返回ostream。我会反过来理解它......
-
你能显示有问题的代码吗?
-
@JETM 当然是的。现在有一个“EDIT 2”提供此信息
标签: c++ file stream persistence overloading