在多个if语句中执行相同的操作,如何减少代码冗余

same operation in multiple if statement, how to reduce code redundancy

本文关键字:操作 何减少 冗余 代码 if 语句 执行      更新时间:2023-10-16

下面的delete语句是一个代码冗余。

int *a = new int[100]
if (!doSomething1(a))
   delete[] a
   return
if (!doSomething2(a))
   delete[] a
   return
if (!doSomething3(a))
   delete[] a
   return
return

我想出的一个替代方案是:

if(doSomething1(a) || doSomething2(a) || doSomething3(a))
   ;
delete[] a;
return;

但它不适合我想添加指定给doSomething1((的指令的情况,例如

if(!doSomething1(a))
   foo;
   delete[] a;
   return;
if(!doSomething2(a))
   delete[] a;
   return;

有人告诉我,至少有5种方法可以减少这种代码冗余。有什么建议吗?


更新,还有一个问题:同样的问题,让我们将域限制为C,注意过程逻辑的变化。

char *a = (char*)malloc(100*sizeof(char));
if(doSomething1(a))
   foo;
   free(a)
   return;
if(doSomething2(a))
   free(a)
   return;
if(doSomething3(a))
   free(a);
   return;
free(a);
return

为什么需要手动删除任何内容?这是C++,所以我们可以使用析构函数和RAII。

std::vector<a>(100);
if (!doSomething1(a))
    return;
if (!doSomething2(a))
    return;
if (!doSomething3(a))
    return;

更一般地说:如果在离开一个作用域时需要发生任何事情,那么在该作用域中的自动对象的析构函数中执行。

但是,为什么要使用返回值来表示失败呢?这是C++,所以我们可以使用异常:

std::vector<a>(100);
doSomething1(a);
doSomething2(a);
doSomething3(a);

"RAII"answers"scope exit"对于Google或SO来说是很好的搜索词。例如,看看Boost。ScopeExit或其替代方案。其想法是创建一个本地对象,并将其留给析构函数来执行清理或"最终"代码。

这里有一个尝试,将这个习惯用法直接应用到您的示例中,减少到最低限度(没有错误检查之类的东西(:

class AutomaticDeleter
{
public:
    AutomaticDeleter(int *a) : a(a) {}
    ~AutomaticDeleter() { delete[] a; }
    int *GetWrappedPointer() const { return a; }
private:
    int *a;
};
// ...
AutomaticDeleter automatic_deleter(new int[100]);
if (!doSomething1(automatic_deleter.GetWrappedPointer()))
   return;
if (!doSomething2(automatic_deleter.GetWrappedPointer()))
   return;
if (!doSomething3(automatic_deleter.GetWrappedPointer()))
   return;

当然,我应该提到的是,这只是可以做什么的一个例子,而不是在将习语应用于指针时,尤其是从new[]返回的指针时,应该做什么。在现实生活中,你会使用std::vector<int>,并且不用它了。这个习语有更多有趣和有用的应用。

bool failure;
int *a = new int[100]
if ( failure = !doSomething1(a))
   //...
if ( !failure && ( failure = !doSomething2(a) ) )
   //...
if ( !failure && ( failure =!doSomething3(a) ) )
   //...
if ( failure )
{
   delete []a;
   return;
}
//,,,   
return
do {
    if (doSomething1(a) && doSomething2(a) && doSomething3(a)){
        break; /*all good: move outside the dummy loop*/
    }
    /*one of the functions failed*/
    delete[] a;
    return;
} while (false);

是一种方式。我所依赖的事实是,if严格从左到右对语句求值,一旦达到false,就会停止求值。

(这个习惯用法在C中使用得很频繁;请参阅unix内核源代码(。