我想创建一个自定义文件流类,该类可用于打印和读取格式化(文本)和未格式化(二进制)数据。移位运算符(<>)以及文件流的写入和读取成员已经存在,但是我只想使用移位运算符<
我编写的代码至少对于字符串和chars(和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的<>运算符不会因char,cstrings和string过载。

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

如果您提供建议并为我的目的显示一个好的做法,我也将不胜感激,因此,也可以接受变通办法-如果它们很优雅。

最佳答案

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


就像上面链接中的Johannes Schaub-litb所建议的那样,我不将shift运算符用作成员函数,而是将其用作自由函数。因此,我必须定义该类的新成员,该成员存储是否以二进制模式打开文件。
移动语义似乎是必要的。否则,字符串,char和cstring输出将无法正常工作(至少,其工作方式与预期的:)不同。
UncleBens的微调答案看起来不错。


首先,定义类:

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;}
}


然后定义重载的插入和提取运算符:

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;
}


仍然欢迎提出评论和答复,作为改进的建议。

关于c++ - 重载二进制移位运算符的第一个参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17626484/

10-11 01:04