Es gibt Zeiten, in denen dies aus Leistungsgründen notwendig ist (ich möchte nicht eine andere Cache-Zeile holen, wenn ich dasselbe Bedürfnis wie eine Fortsetzung habe; manchmal).
Wenn Sie Ressourcen (Speicher, Dateideskriptoren, Sperren usw.) zuweisen, ohne RAII zu verwenden, können mehrfache Rückgaben fehleranfällig sein und sind mit Sicherheit doppelt, da die Freigaben mehrfach manuell erfolgen müssen und Sie den Überblick behalten müssen.
In diesem Beispiel:
function()
{
HRESULT error = S_OK;
if(SUCCEEDED(Operation1()))
{
if(SUCCEEDED(Operation2()))
{
if(SUCCEEDED(Operation3()))
{
if(SUCCEEDED(Operation4()))
{
}
else
{
error = OPERATION4FAILED;
}
}
else
{
error = OPERATION3FAILED;
}
}
else
{
error = OPERATION2FAILED;
}
}
else
{
error = OPERATION1FAILED;
}
return error;
}
Ich hätte es so geschrieben:
function() {
HRESULT error = OPERATION1FAILED;//assume failure
if(SUCCEEDED(Operation1())) {
error = OPERATION2FAILED;//assume failure
if(SUCCEEDED(Operation3())) {
error = OPERATION3FAILED;//assume failure
if(SUCCEEDED(Operation3())) {
error = OPERATION4FAILED; //assume failure
if(SUCCEEDED(Operation4())) {
error = S_OK;
}
}
}
}
return error;
}
Das scheint auf jeden Fall besser zu sein.
Dies ist besonders hilfreich, wenn es um die manuelle Freigabe von Ressourcen geht, da die Frage, wo und welche Freigaben erforderlich sind, ziemlich einfach zu beantworten ist. Wie im folgenden Beispiel:
function() {
HRESULT error = OPERATION1FAILED;//assume failure
if(SUCCEEDED(Operation1())) {
//allocate resource for op2;
char* const p2 = new char[1024];
error = OPERATION2FAILED;//assume failure
if(SUCCEEDED(Operation2(p2))) {
//allocate resource for op3;
char* const p3 = new char[1024];
error = OPERATION3FAILED;//assume failure
if(SUCCEEDED(Operation3(p3))) {
error = OPERATION4FAILED; //assume failure
if(SUCCEEDED(Operation4(p2,p3))) {
error = S_OK;
}
}
//free resource for op3;
delete [] p3;
}
//free resource for op2;
delete [] p2;
}
return error;
}
Wenn Sie diesen Code ohne RAII (vergessen Sie das Problem der Ausnahmen!) mit mehreren Exits schreiben, müssen die Löschungen mehrfach geschrieben werden. Wenn Sie ihn mit }else{
dann wird es ein bisschen hässlich.
Aber RAII macht das Problem der Mehrfachausgangsressourcen überflüssig.
25 Stimmen
Ich stimme nicht zu, dass die Frage sprachenfeindlich ist. Bei einigen Sprachen ist die Mehrfachrückgabe natürlicher und bequemer als bei anderen. Ich würde mich eher über frühe Rückgaben in einer C-Funktion beschweren als in einer C++-Funktion, die RAII verwendet.
3 Stimmen
Diese Frage ist eng damit verbunden und enthält ausgezeichnete Antworten: programmers.stackexchange.com/questions/118703/
0 Stimmen
Sprachunabhängig? Erklären Sie jemandem, der eine funktionale Sprache verwendet, dass er einen Return pro Funktion verwenden muss :p