2

我试图在我的应用程序中多次使用 FILE 指针,尽管我创建了一个函数并将指针传递给它。基本上我有这段代码

     FILE* fp;
    _wfopen_s (&fp, L"ftest.txt", L"r");
    _setmode (_fileno(fp), _O_U8TEXT);
    wifstream file(fp);

这是重复的,现在我想要这样的东西:

wifstream file(SetFilePointer(L"ftest.txt",L"r"));
....
wofstream output(SetFilePointer(L"flist.txt",L"w"));

和功能:

FILE* SetFilePointer(const wchar_t* filePath, const wchar_t * openMode)
{
    shared_ptr<FILE> fp = make_shared<FILE>();
    _wfopen_s (fp.get(), L"ftest.txt", L"r");
    _setmode (_fileno(fp.get()), _O_U8TEXT);
    return fp.get();
}

这不简单。我尝试使用&*fp而不是,fp.get()但仍然没有运气。

4

1 回答 1

3

您不应该像使用一样创建FILE实例new并使用 销毁它们。相反,s 是用(或在这种情况下,)创建并用 销毁的。这些函数使用一些未指定的方式在内部进行分配和解除分配。deletemake_sharedFILEfopen_wfopen_sfclose

请注意,_wfopen_s它不需要指针而是指向指针的指针- 它会将您给它的指针更改为指向FILE它分配的新对象。您无法获取包含在其中的指针的地址shared_ptr来形成指向它的指针,这是一件非常好的事情 - 它会严重破坏所有权语义shared_ptr并导致内存泄漏或更糟。

但是,您可以使用它shared_ptr来管理任意类似“句柄”的类型,因为它可以采用自定义删除器对象或函数:

FILE* tmp;
shared_ptr<FILE> fp; 
if(_wfopen_s(&tmp, L"ftest.txt", L"r") == 0) {
  // Note that we use the shared_ptr constructor, not make_shared
  fp = shared_ptr<FILE>(tmp, std::fclose);
} else {
  // Remember to handle errors somehow!
}

请查看@KerrekSB 给出的链接,它更详细地涵盖了同样的想法。

于 2013-07-21T12:29:21.293 回答