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