Как преобразовать между shared_ptr<FILE> в FILE* в C++?

Я пытаюсь использовать указатель 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() но все равно не повезло.

1 ответ

Решение

Вы не должны создавать FILE случаи с new и уничтожить их delete, лайк make_shared делает. Вместо, FILEс созданы fopen (или в этом случае _wfopen_s) и уничтожен fclose, Эти функции выполняют распределение и освобождение изнутри, используя некоторые неуказанные средства.

Обратите внимание, что _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, она охватывает эту же идею более подробно.

Другие вопросы по тегам