2017-02-17 171 views
0

我努力想办法避免多个return语句,使资源,这种清理没有得到复制,使我找到了以下几种方式:方法避免多次return语句

  1. 使用宏,执行如果错误不正确,清理。

    #define EXE(x) if (OK != (err = x)) goto cleanup; 
    
    ErrorCode func() 
    { 
        ErrorCode err = OK; 
    
        EXE (fn1()); 
        EXE (fn2()); 
    
    cleanup: 
        // do cleanup of resources 
        return err; 
    } 
    
  2. 使用do ...而()休息的时候发生错误

    ErrorCode func() 
    { 
        ErrorCode err = OK; 
        do 
        { 
         err = fn1(); 
         if (err != OK) break; 
    
         err = fn2(); 
         if (err != OK) break; 
    
        } while (false); 
    
        // do cleanup of resources 
        return err; 
    } 
    

两种方式允许资源的清理工作在一个地方(立即返回语句以上),提高了可读性。有没有其他方法可以避免多重回报?

+1

这看起来更像是C而不是C++。通常析构函数被用于“清理干净”,所以具有多个回报真的不是问题。 –

+0

确切地说,在C++中,“清理”部分通常会消失。无论如何,你有一些宏观方法 - 它基本上是Haskell的符号。也就是说,我不推荐使用C++中的宏。 – chris

+0

函数的向量,并在循环中执行它们。 –

回答

1

你不需要求助于goto来清理C++中的东西。在自动作用域中构建的所有对象都将被破坏。他们必须负责清理。

也就是说,您可以使用宏来简化错误检查代码的写入。

#define CHECK_ERROR(x) if (OK != x) return x; 

ErrorCode func() 
{ 
    ErrorCode err = OK; 

    err = fn1(); 
    CHECK_ERROR(err); 

    err = fn2(); 
    CHECK_ERROR(err); 

    return err; 
} 

更新,响应OP的评论

使用一个辅助类调用CloseHandle

struct HandlerMinder 
{ 
    HandleMinder(ErrorCode& err, HANDLE hObject) : 
     err_(err), hObject_(hObject) {} 

    ~HandleMinder() 
    { 
     // Adapt the logic to suit your needs. 
     if (err_ != OK) 
     { 
     CloseHandle(hObject_); 
     } 
    } 

    ErrorCode& err_; 
    HANDLE hObject_; 
}; 

ErrorCode func() 
{ 
    ErrorCode err = OK; 
    HANDLE object = <some handle>; 
    HandleMinder m(err, object); 

    err = fn1(); 
    CHECK_ERROR(err); 

    err = fn2(); 
    CHECK_ERROR(err); 

    return err; 
} 
+0

如果函数得到资源清理(内存/句柄/ ..),不需要适合成为一个成员var? – object

+0

显示您的想法。一般来说,这通常不是问题。 –

+1

内存分配可以使用智能指针来处理,但是可以用其他方法完成,比如Windows对象的“CloseHandle”或COM中出现的一种Release方法,这些方法不需要成为仅用于解除分配的成员析构函数? – object