提问人:reallyhuh 提问时间:8/21/2023 最后编辑:273Kreallyhuh 更新时间:8/21/2023 访问量:59
这种用于方便二进制输出的 C++ fstream 继承的实现如何导致无法打开文件?
How is this implementation of inheritance of C++ fstream for convienient binary output causing failure opening the file?
问:
代码输出,“文件未打开”。
union converter_t {
char byte[4];
short int word[2];
int dword[1];
} converter;
class enhancedfstream: public fstream {
public:
enhancedfstream(string s, _Ios_Openmode iosom) {
fstream(s, iosom);
}
void write(int i) {
converter.dword[0] = i;
fstream::write(converter.byte, 4);
}
void write(short int si) {
converter.word[0] = si;
fstream::write(converter.byte, 2);
}
void write(string s) {
char* tca = &s[0];
fstream::write(tca, s.length());
}
void write(char c) {
// intended correction:
converter.byte[0] = c;
fstream::write(converter.byte, 1);
// as original, before correction:
// fstream::write(new char[1] {c}, 1);
}
void write(char* cp, int i) {
fstream::write(cp, i);
}
};
enhancedfstream fs(fn, fstream::out | fstream::binary | fstream::trunc);
if (fs.is_open()) {} else cout << "file not open\n";
从 shell 查看 Linux 文件系统显示空文件创建成功,但以编程方式显示文件未打开,后续写入无效。编译和执行是在根目录的子目录中以 root 身份完成的。在 ipadOs iSH 1.3.2(内部版本 494)中使用模拟的 g++ (Alpine 10.3.1_git20210424) 10.3.1 20210424 (C++14)(版权所有 2020)编译。
上面实现的继承是不正确的,还是 fstream 在如何成功地被子类化方面是特殊的?缓冲区设置是否无人值守?标准报告的 fstream 打开失败原因似乎不存在,除非 null 缓冲区导致打开失败。具有相同规格的非子类 fstream 可以正常打开。
答:
1赞
Ted Lyngmo
8/21/2023
#1
在构造函数中构造一个临时函数。该临时值在完整表达式的末尾关闭。fstream
fstream
fstream(s, iosom); // opened and closed immediately
此外,是特定于内部实现的类型。不要使用那些。_Ios_Openmode
使用成员初始值设定项列表初始化基类:
enhancedfstream(const std::string& s, std::ios_base::openmode iosom)
: std::fstream(s, iosom) // now opened correctly
{
// empty constructor body
}
旁注:s
fstream::write(new char[1] {c}, 1);
不是一个好主意。它将分配永远不会释放的内存。使用或简单地使用write(&c, 1);
put(c);
- 全局不会做任何事情来简化实现。但是,它确实使同时在多个线程中使用 your 变得不安全。
converter
enhancedfstream
- 不要对 和 的大小进行硬编码。它们并不总是 4 个字节和 2 个字节。
int
short int
评论
0赞
Ted Lyngmo
8/21/2023
@reallyhuh 正如所写的那样,它确实编译得很好。演示
0赞
reallyhuh
8/21/2023
这里的东西乱七八糟。那里提到的主要解决方案就像*实际编写的那样工作。
0赞
Ted Lyngmo
8/21/2023
@reallyhuh太棒了!很高兴它成功了!
0赞
reallyhuh
8/21/2023
int 和 char 大小以及所有这些代码并不意味着除了特定于实现之外,以及数据存储的小端方法。(请不要砍我,或者把我传给那些愿意的人?都不是!
0赞
Ted Lyngmo
8/21/2023
@reallyhuh 如果你问演示网站是否可以信任,那么我会说是的。在分享简短演示时,它是 SO 上人们最常用(如果不是最常用)的之一。“int 和 char 大小以及所有这些代码根本不意味着特定于实现”——好吧,我仍然会用它来表示意图。此外,如果以后要使用函数模板对其进行泛化,则大部分位都已到位。sizeof
评论
new char[1] {c}
union
std::variant