2017-09-23 71 views
0

我試圖環繞FILE *類,這裏是分配失敗的FILE *類

class file_ptr 
{ 
    public: 
     file_ptr(const wstring& _FileN, const wstring& _OpenMode) : file_n(_FileN), omode(_OpenMode), 
     fptr(_wfopen(file_n.c_str(), omode.c_str())) 
     { 
      if (!fptr) 
       throw wstring(L"Failed to open File ") + _FileN; 
     } 

     ~file_ptr() 
     { 
      fclose(fptr); 
     } 

     file_ptr& operator =(const file_ptr& other) 
     { 
      if (this != &other) 
      { 
       this->~file_ptr(); 
       fptr = other.fptr; 
       file_n = other.file_n; omode = other.omode; 
      } 
     } 

     operator FILE*() { return fptr; } 

    private: 
     wstring file_n, omode; 
     FILE* fptr; 
}; 

爲什麼wstring的?我需要Unicode支持。

現在的問題可以說是做了這樣的事情

int main() { 
    try { 
     file_ptr file1(L"text1",L"wb"); 
     fwrite("Hello",1,5,file1); 
     file1 = file_ptr(L"text2",L"wb"); 
     fwrite("Hello",1,5,file1); 
    } catch (const wstring& e) { 
     wcout << e << endl; 
    } 
    return 0; 
} 

什麼都不會寫在文本2

我甚至試着刪除我的任務過載後,becoz我想默認的行爲應該是一樣的,但問題仍然存在

它的工作原理,如果我使用*預期FE

int main() { 
    try { 
     FILE* file1 = _wfopen(L"text1",L"wb"); 
     fwrite("Hello",1,5,file1); 
     fclose(file1); 
     file1 = _wfopen(L"text2",L"wb"); 
     if (!(file1)) 
      throw L"Can't open file"; 
     fwrite("Hello",1,5,file1); 
    } catch (const wstring& e) { 
     wcout << e << endl; 
    } 
    return 0; 
} 
RAW文件

text2的正確寫入,

+2

爲什麼要手動調用析構函數? – Brandon

+0

你打算如何在'FILE *'上使用'WCHAR'? – stackptr

+0

將它轉換爲char *並在字符串之前存儲大小和長度 – bluedragon

回答

3

file1 = file_ptr(L"text2",L"wb");表達創建臨時file_ptr對象,然後fptr = other.fptr;複製由臨時對象所擁有的FILE指針值。臨時對象被立即銷燬並關閉文件指針,並將file1指向FILE指針。你應該寫一招賦值運算符來代替:

file_ptr & 
operator =(const file_ptr & other) = delete; // prevent accidental use 

file_ptr & 
operator =(file_ptr && other) noexcept 
{ 
    if(this == ::std::addressof(other)) 
    { 
     ::std::terminate(); // there is no context when selfassignment makes sense 
    } 
    //this->~file_ptr(); calling destructor on itself is no good 
    ::fclose(this->fptr); 
    this->fptr = other.fptr; 
    other.fptr = 0; 
    this->file_n = ::std::move(other.file_n); 
    this->omode = ::std::move(other.omode); 
    return(*this); 
} 

正如評論所說,這將是禁止拷貝構造函數和實現移動構造函數,以防止施工過程中出現的類似問題是個好主意。您可能還想檢查Rule-of-Three becomes Rule-of-Five with C++11?

+0

感謝您的回答。我可以禁用這種行爲嗎? – bluedragon

+0

謝謝,現在它正在工作。 – bluedragon

+1

請注意,您還應該禁用編譯器生成的拷貝構造函數,然後考慮實現移動構造函數。 – aschepler