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

时间:2014-03-12 16:18:52

标签: c++ redundancy

下面的删除声明是代码冗余。

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

4 个答案:

答案 0 :(得分:2)

为什么需要手动删除任何内容?这是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);

答案 1 :(得分:1)

“RAII”和“范围退出”将是Google或SO的良好搜索字词。例如,请查看Boost.ScopeExitalternatives to it。我们的想法是创建一个本地对象并将其留给析构函数来进行清理或“最终”代码。

这是尝试将这个成语直接应用到你的例子中,减少到最低限度(没有错误检查和类似的东西):

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>并完成它。这个成语有更多有趣和有用的应用程序。

答案 2 :(得分:0)

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内核源代码)。

答案 3 :(得分:0)

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