编码标准/编码C++中的最佳实践

pan*_*ajt 9 c++ coding-style

考虑下面的两个代码段.哪一个更好,为什么?如果您有任何其他想法,请提及.我在哪里可以找到像这样的编码实践的答案?如果您知道任何书籍/文章,请分享.

//代码1

bool MyApplication::ReportGenerator::GenerateReport(){
    bool retval = false;
    do{
        if (!isAdmin()){
            break;
        }
        if (!isConditionOne()){
            break;
        }
        if (!isConditionTwo()){
            break;
        }
        if (!isConditionThree()){
            break;
        }

        retval = generateReport();
    } while(0);
    return retval;
}
Run Code Online (Sandbox Code Playgroud)

//代码2

bool MyApplication::ReportGenerator::GenerateReport(){
    if (!isAdmin()  || !isConditionOne() || !isConditionTwo() || !isConditionThree()){
        return false;
    }
    return generateReport();
}
Run Code Online (Sandbox Code Playgroud)

罗伯特C.马丁的清洁代码是一本很好的书来处理这个问题.但是,我想这本书倾向于Java.

更新:

  1. 我故意使用do {} while(0); 因为我不想使用goto循环.

  2. 我想摆脱这么多if和break语句,所以我提出了Code 2.

我从回复中看到的是Code1和Code2的一组混合响应.与Code 1(我认为更好)相比,有些人更喜欢goto.

And*_*ite 40

我真的不喜欢以这种方式使用do/while循环.另一种方法是将Code2中的条件分解为单独的if检查.这些有时被称为"保护条款".

bool MyApplication::ReportGenerator::GenerateReport()
{
    if (!isAdmin())
        return false;

    if (!isConditionOne())
        return false;

    // etc.

    return generateReport();

}
Run Code Online (Sandbox Code Playgroud)

  • 阿门!我从未理解"不允许提前退货"的心态.它导致了这种混乱,一个糟糕的编码器感觉他们必须被迫在变态循环结构和使用goto之间. (15认同)
  • 此外,这种技术比在一个`if`语句中放置大量函数调用更安全,如果这些函数中的任何一个具有副作用,则可能无法保证评估顺序. (2认同)

csj*_*csj 26

我个人更喜欢你的第二个代码段的变体.短路将起作用,但条件不太冗长.

bool MyApplication::ReportGenerator::GenerateReport()
{
    if(isAdmin() && isConditionOne() && isConditionTwo() && isConditionThree())
    {
        return generateReport();
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

它说一切都在一个干净的地方."如果满足所有这些条件,那么就这样做.否则,不要这样做."

我觉得你的第一个代码段通过将条件分布在12行中使得逻辑变得更难看.此外,封装循环可能会导致某人进行双重操作.


小智 17

bool MyApplication::ReportGenerator::GenerateReport()
{
   return isAdmin()  
      && isConditionOne() 
      && isConditionTwo()
      && isConditionThree()
      && generateReport();    // Everything's ok.
}
Run Code Online (Sandbox Code Playgroud)

  • +1,很好用短路评估. (4认同)
  • 很好,但对我来说太过"聪明"了.当我读到它时,我需要在达到generatReport()表达式时精神上改变齿轮. (4认同)
  • 不,不要这样做。这比使用switch和break模拟goto还要糟糕。 (2认同)

小智 8

bool MyApplication::ReportGenerator::GenerateReport(){
    if ( ! isAdmin         () ) return false ;
    if ( ! isConditionOne  () ) return false ;
    if ( ! isConditionTwo  () ) return false ;
    if ( ! isConditionThree() ) return false ;
    return generateReport() ;
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*ier 6

这实际上取决于代码的未来期望.上面的Code1暗示可能为每个条件添加额外的逻辑; 上面的代码2意味着有一个合理的条件分组.如果您希望以后为条件添加逻辑,则Code1可能更相关; 但是,如果你不这样做,Code2可能因为简洁和隐含的分组而更加明智.


Bil*_*ill 5

我更喜欢修改样本2:

bool MyApplication::ReportGenerator::GenerateReport()
{
    bool returnValue = false;
    if (isAdmin() &&
        isConditionOne() &&
        isConditionTwo() &&
        isConditionThree())
    { 
        returnValue = generateReport();
    } 
    return returnValue;
}
Run Code Online (Sandbox Code Playgroud)

它具有为该功能提供单个出口点的优点,建议使用该出口以便于维护.我发现垂直堆叠条件而不是水平更容易快速读取,如果需要,可以更容易地评估各个条件.