2013-07-13 94 views
1

我想創建一個自定義文件流類,我可以用它來打印和讀取格式化(文本)和無格式(二進制)數據。移位運算符(< <和>>)已經存在,以及文件流的寫入和讀取成員,但是我只想使用移位運算符< <,並且在以二進制模式打開流時創建未格式化的輸出,以及否則格式化。重載二進制移位運算符的第一個參數

我寫不至少字符串和字符(和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的< <和>>運營商都不會超載與chars,cstrings和字符串。

你能指出我應該在哪裏修改我的代碼,我應該替換什麼?

如果您提供建議並展示我的目標的良好實踐,我也很感激,所以也接受解決方法 - 如果它們很優雅。

+0

參數'(T && param)'是否暗示<<插入操作符將對象向右? – thb

+1

@thb是的。它會。 T &&是移動語義。 –

回答

0

基於另一個題爲「Problem with overriding 「operator<<」 in class derived from 「ostream」」的SO問題,我可以實現我的目標。

  1. As Johannes Schaub - litb在上面的鏈接中提出建議,我不使用shift運算符作爲成員函數,我將它用作自由函數。因此,我必須定義一個類的新成員,用於存儲文件是否以二進制模式打開。
  2. 移動語義似乎是必要的。沒有那個,字符串,char和cstring輸出不能正常工作(至少,工作方式與預期不同:))。
  3. 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;} 
} 

,然後定義重載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; 
} 

評論和答案仍然存在歡迎作爲改進建議。

相關問題