Otwarcie pliku - czy opłaca się stosować RAII?

Otwarcie pliku - czy opłaca się stosować RAII?
Shizzer
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 231
0

Mam taki kod:

Kopiuj
bool create_result_file(std::fstream& result_file, const std::string& result_filename) {
	result_file.open(result_filename, std::fstream::out);
	if (!result_file.good()) {
		return false;
	}
	return true;
}

int main(int argc, char *argv[])
{
	std::fstream result_file;
	std::string result_filename = argv[2];
	if (!create_result_file(result_file, result_filename)) {
		std::cerr << "Can not create or open the result file.\n";
		return 3;
	}

	result_file << "Asdf";
	std::cout << "Result file created successfully.\n";
    result_file.close();
	return 0;
}

Czy w przypadku gdy w module programu otwieram plik tylko raz nadal opłaca się zastosować RAII tak, żeby nie przejmować się manualną dealokacją zasobu? Oczywiście gdyby wystąpił exception gdzieś między otwarciem pliku, a jego zamknięciem wówczas doszłoby do wycieku pamięci. Zatem moje pytanie brzmi - czy zawsze należy implementować klasę do otwarcia zasobu, która dbałaby o to, żeby ten zasób był zwalniany "automatycznie"?

I jeszcze jedno - co by się stało gdyby poleciał exception podczas wykonywania metody good w 3. linijce kodu? Nastąpiłby wyciek wszystkich zmiennych zaalokowanych w main czy wyciekłby jedynie obiekt result_file?

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
4

fstream jest dobrą klasą i wywołuje close() kiedy trzeba. Więc pytanie należy raczej postawić: czy utrudniać sobie życie i celowo szukać trudniejszych sposobów, aby mieć mniej bezpieczny program? IMO odpowiedź to "nie".

Shizzer
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 231
0

Czyli tylko w przypadku zastosowania na przykład naleciałości z C typu FILE * i fopen musiałbym sobie to RAII rozważyć? Rzecz jasna biorę tu pod uwagę tylko zasób plikowy.

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
3

Tak, wtedy byś musiał - i imo byłoby to zasadne. Albo za pomocą unique_ptr, albo jakiejś klasy podobnej do resource

stryku
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 607
3

Jeszcze odpowiadając na pytanie o wyjątek.
Gdyby w good() poleciał wyjątek, to stos by się pozwijał i wywołał destruktory wszystkich* obiektów, które na stosie napotka (plus statyczne obiekty też opendzluje). Czyli u Ciebie destruktory result_file i result_filename się wywołają.
** wszystkich, których stworzenie się powiodło. Np. jak masz klasę i w jej konstruktorze rzucisz wyjątkiem, to destruktor dla tej konkretnej instancji sie nie wywoła.

czy wyciekłby jedynie obiekt result_file?

Kurde szczerze powiem, że to zdanie mi się nie klei. Nie da rady, żeby result_file wyciekł bo ma auto storage duration (jest na stosie). Wyciec może pamięć, która ma dynamic storage duration (na stercie).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.