2016-06-04 5 views
-3

Was ist der Vorteil der Verwendung der Verwendung eines unique_ptr Destruktor über nur das Schließen der Datei direkt in C++ 11?unique_ptr destructor Vorteil

d.h. Dieser Code

FILE* p = fopen("filename","r"); 
unique_ptr<FILE, int(*)(FILE*)> h(p, fclose); 
if (fclose(h.release()) == 0) 
    p = nullptr; 

vs.

FILE* p = fopen("filename","r"); 
fclose(p) 
+5

Sie brauchen nur: '{std :: unique_ptr h (std :: fopen (" dateiname "," r "), std :: fclose); } '. Das ist es. –

+0

Ja, wird so lange funktionieren, wie ich das unique_ptr nicht kopieren möchte, wenn h eine Mitgliedsvariable wäre. – Damian

Antwort

5

Die beiden letzten Zeilen des ersten Codeblock nicht benötigt werden. Außerdem machst du nichts mit der Datei. Da wird der Vorteil offensichtlich.

Mit unique_ptr, planen Sie die fclose() Aufruf einmal, wenn Sie die Datei öffnen, und sorgen Sie sich nie wieder darüber.

Mit C-Stil, haben Sie eine Menge Code in zwischen fopen() und fclose() und müssen sicherstellen, dass keines dieser Code über die fclose() springen können.

Hier ist ein realistischer Vergleich:

typedef std::unique_ptr<FILE, int(*)(FILE*)> smart_file; 
smart_file h(fopen("filename", "r"), &fclose); 
read_file_header(h.get()); 
if (header.invalid) return false; 
return process_file(h.get()); 

vs

FILE* p = fopen("filename","r"); 
try { 
    read_file_header(p); 
} 
catch (...) { 
    fclose(p); 
    throw; 
} 
if (header.invalid) { 
    fclose(p); 
    return false; 
} 
try { 
    auto result = process_file(p); 
    fclose(p); 
    return result; 
} 
catch (...) { 
    fclose(p); 
    throw; 
} 

über die fclose() Springen kann viele Formen annehmen: return, if, break, continue, goto, throw. Der C++ - Compiler handhabt alle von ihnen, wenn Sie einen intelligenten Zeiger verwenden.

+0

In den letzten beiden Zeilen wird der Zeiger auf Null gesetzt. Aber ich stimme zu, nicht unbedingt notwendig. – Damian

+0

@Damian: Aber warum würdest du das überhaupt machen? Setzen Sie auch alle Ihre int-Variablen auf "0", bevor sie den Gültigkeitsbereich verlassen? – ildjarn

+0

@ildjarn: Plus, 'h.reset();' hätte den Trick gemacht, außer für den Teil über das Erkennen eines Fehlers von 'fclose()'. Ich kann mir nicht vorstellen, was es gut macht, wenn man weiß, dass eine Datei gescheitert ist. –