2017-09-23 10 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サポートが必要です。

は、今の問題は、それがテキスト2

私はデフォルトの動作は同じであるべきと仮定becoz私も、私の割り当ての過負荷を取り除いた後にしようとしたに書き込まれます。この

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

何もないような何かをしたと言うことができますしかし、問題は、私は期待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ファイルを使用している場合、それは動作します

を持続します

テキスト2は

+2

なぜあなたは手動でデストラクタを呼び出していますか? – Brandon

+0

'FILE *'に 'WCHAR'をどのように使う予定ですか? – stackptr

+0

char *としてキャストし、文字列の前にサイズと長さを格納する – bluedragon

答えて

3

file1 = file_ptr(L"text2",L"wb");式は一時file_ptrオブジェクト、その後fptr = other.fptr;コピーし、一時オブジェクトが所有するFILEポインタ値を作成し、正しく書き込まれています。 Tempオブジェクトは即座に破棄され、ファイルポインタを閉じて、FILEポインタを持つfile1を残します。代わりに、移動代入演算子を記述する必要があります。

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

関連する問題