在第一个参数中重载二进制移位运算符

时间:2013-07-13 02:44:16

标签: c++ operator-overloading filestream binary-operators

我想创建一个自定义的文件流类,我可以用它来打印和读取格式化(文本)和未格式化(二进制)数据。移位运算符(<<>>)已经存在,以及文件流的写入和读取成员,但我想使用移位运算符<<只有,如果以二进制模式打开流,则创建无格式输出,否则格式化。

我编写的代码至少对字符串和字符(以及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 *) &param, 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 *) &param, 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和字符串。

您能指出我应该在哪里修改我的代码以及我应该将其替换为什么?

如果您提出建议并为我的目的展示良好的实践,我也将不胜感激,因此,如果它们很优雅,也可以接受解决方法。

1 个答案:

答案 0 :(得分:0)

基于另一个标题为“Problem with overriding “operator<<” in class derived from “ostream””的SO问题,我可以实现我的目标。

  1. 正如Johannes Schaub - litb在上面的链接上建议的那样,我不使用shift运算符作为成员函数,我将它用作自由函数。因此,我必须定义该类的新成员,该成员存储文件是否以二进制模式打开。
  2. 移动语义似乎是必要的。没有它,字符串,char和cstring输出不能正常工作(至少,工作方式与预期不同:))。
  3. UncleBens对调整的回答看起来很不错。
  4. 首先,定义类:

    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 *) &param, sizeof(param));
    
        else
            (fstream&)stream << param;
    
        return stream;
    }
    
    template <class T> mixstream& operator>> (mixstream& stream, const T&& param)
    {
        if (stream.get_binmode())
            read((char *) &param, 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;
    }
    

    仍然欢迎评论和回答作为改进建议。