我想创建一个自定义的文件流类,我可以用它来打印和读取格式化(文本)和未格式化(二进制)数据。移位运算符(<<>>)已经存在,以及文件流的写入和读取成员,但我想使用移位运算符<<只有,如果以二进制模式打开流,则创建无格式输出,否则格式化。
我编写的代码至少对字符串和字符(以及cstrings)没有正常工作:
class mixstream:public fstream {
public:
//some constructors and public functions in the code
template <class T> mixstream& operator<< (T&& param)
{
if (openmode() & ios_base::binary)
write((char *) ¶m, sizeof(param)); //binary write-out
else
fstream::operator<<(param); //non-binary write out
return *this;
}
template <class T> mixstream& operator>> (T&& param)
{
if (openmode() & ios_base::binary)
read((char *) ¶m, sizeof(param)); //binary read-in
else
fstream::operator>>param; //non-binary read-in
return *this;
}
};
问题可能在ostream's shift operator左右,因此ostream的&lt;&lt;和&gt;&gt;运算符不会超出chars,cstrings和字符串。
您能指出我应该在哪里修改我的代码以及我应该将其替换为什么?
如果您提出建议并为我的目的展示良好的实践,我也将不胜感激,因此,如果它们很优雅,也可以接受解决方法。
答案 0 :(得分:0)
基于另一个标题为“Problem with overriding “operator<<” in class derived from “ostream””的SO问题,我可以实现我的目标。
首先,定义类:
class mixstream:public fstream
{
bool binmode;
public:
//constructors
explicit mixstream() {};
explicit mixstream ( const char * filename, ios_base::openmode mode = ios_base::in | ios_base::out) :
fstream(filename, mode)
{
if (mode & ios_base::binary)
binmode = true;
else
binmode = false;
};
void open(const char *_Filename, ios_base::openmode _Mode = ios_base::in | ios_base::out, int _Prot = (int)ios_base::_Openprot)
{
fstream::open (_Filename, _Mode, _Prot);
if (_Mode & ios_base::binary)
binmode = true;
else
binmode = false;
}
bool get_binmode() const {return binmode;}
}
然后定义重载的insertation和extractation操作符:
template <class T> mixstream& operator<< (mixstream& stream, const T&& param)
{
if (stream.get_binmode())
stream.write((char *) ¶m, sizeof(param));
else
(fstream&)stream << param;
return stream;
}
template <class T> mixstream& operator>> (mixstream& stream, const T&& param)
{
if (stream.get_binmode())
read((char *) ¶m, sizeof(param));
else
ostream::operator>>param;
return *this;
}
那么我可以在表单中使用我的新流:
int main(int argc, char *argv[]) {
mixstream bin_or_not;
if (true) //some condition
bin_or_not.open("file.dat",ios_base::out | ios_base::binary);
else
bin_or_not.open("file.dat",ios_base::out);
char testcs[] = "testsc";
string tests("tests");
int testn = 10;
bin_or_not << 10 << testn << "testcs" << testcs << tests;
return 0;
}
仍然欢迎评论和回答作为改进建议。