Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Switch语句而不是多个嵌套的if-else?_C++_Conditional Statements_Nested If - Fatal编程技术网

C++ Switch语句而不是多个嵌套的if-else?

C++ Switch语句而不是多个嵌套的if-else?,c++,conditional-statements,nested-if,C++,Conditional Statements,Nested If,我遇到了一种情况,我有一堆“系统”需要按顺序初始化,只有当所有正在进行的系统都成功初始化时,下一个系统才会被初始化 这让我想到了大量嵌套的if-else语句。下面是一些用于可视化的伪代码 bool mainInit () { if (!system1Init ()) { reportError (); // some error reporting function } else { if (!system2Init ()) {

我遇到了一种情况,我有一堆“系统”需要按顺序初始化,只有当所有正在进行的系统都成功初始化时,下一个系统才会被初始化

这让我想到了大量嵌套的if-else语句。下面是一些用于可视化的伪代码

bool mainInit () {
    if (!system1Init ()) {
        reportError ();  // some error reporting function
    }
    else {
        if (!system2Init ()) {
            reportError ();
        }
        else {
            if (!system3Init ()) {
            // ... and so on
我发现,当你达到一点点水平时,这看起来就像一团乱

现在我想用一个switch语句来代替,从第一个案例开始,到其他成功案例,只有在出现错误时才会中断

bool mainInit () {

    switch (1) {
    case 1:
        if (!system1Init ()) {
            reportError ();
            break;
        }
    case 2:
        if (!system2Init ())
            reportError ();
            break;
        }
    // ....
}
现在,我更喜欢这个。我发现它更容易阅读,特别是有一些像样的评论,但我对编程相当陌生

所以,我的问题是:看看这不是switch语句的传统用法(至少从我所看到的情况来看),这样的东西是可以接受的,还是会被认为是不好的形式

作为一名编程新手,我尽量避免养成太多的坏习惯,因为这些坏习惯可能会让其他程序员感到沮丧和困难


我做了一次搜索,但我发现的大部分内容都与替换if-else if语句链有关,而不是替换嵌套语句。

引用数组中的所有系统,例如
std::vector
,并按顺序循环它们,在第一次失败时中断。这样,即使对于500多个系统,您的整个代码也会减少到5行以下


建议的切换黑客是一个邪恶的例子:您真正的问题是您没有系统数组,并且正在使用命名变量,因此消除了所有选项以更灵活地使用所有系统,例如在循环中。

假设您的
系统#Init()
调用在编译时已知,您可以很容易地将它们放在一个表中,然后在该表上进行迭代

typedef (*system_init)(void);

system_init initialization_functions[] =
{
    system1Init,
    system2Init,
    system3Init,
      ...
    systemNInit
};

bool mainInit()
{
    for(size_t idx(0); idx < sizeof(initialization_functions) / sizeof(initialization_functions[0]); ++idx)
    {
        if(!initialization_functions[idx]())
        {
            ReportError();
            return false;
        }
    }
    return true;
}
这个开关能回答你的问题吗?不是像上面写的那样。也就是说,如果您想使用计数器调用
mainInit()
函数,它可能会很有用。Drupal使用这种机制:

bool mainInit(int idx)
{
    bool r(true);
    switch(idx)
    {
    case 1:
        r = system1Init();
        break;

    case 2:
        r = system2Init();
        break;

    [...]
    }
    if(!r)
    {
        ReportError();
    }
    return r
}
请注意,工作台机制的工作方式与开关相同。只要所有代码都在
systemniit()
函数中找到(应该是这样),开关就不会添加任何内容,因此您也可以这样做:

bool mainInit(int idx)
{
    if(idx < 0 || idx >= sizeof(initialization_functions) / sizeof(initialization_functions[0]))
    {
        throw std::range_error("index out of bounds");
    }
    if(!initialization_functions[idx]())
    {
        ReportError();
        return false;
    }
    return true;
}

使用带有明确错误消息的自定义异常,并在
main()
中的代码周围添加try-catch报告。例外情况是通过隐式“坏路径”使您的案例看起来很好

void initX() { ...; throw std::invalid_argument_exception("..."); }

int main() {
    try {
        init1(); init2(); ... run();
        return 0;
    } catch (std::exception const& e) {
        log(e.what()); exit 42;
    }
}
我会这样做:

bool mainInit () {
  if (!system1Init ()) {
    return(false);
  }

  if (!system2Init ()) {
    return(false);
  }

  if (!system3Init ()) {
    return(false);
  }

  //...                 

  return(true);
}

//...

if(!mainInit()) {
  reportError();
}

在所有if语句之后会出现什么?
mainInit
返回什么?失败时
returnfalse
throw…
如何?您不必执行
else{if(){/code>大多数人都执行
else if(){
@Beta抱歉,如果所有系统都成功初始化,则返回true;如果出现任何故障,则返回false。在我的问题中,我在代码中犯了一个错误,我没有直接处理系统对象(我甚至不确定所有系统下面是否有对象)我正在初始化c库的一部分以供使用。我很抱歉。我想我没有真正理解我应该问的是什么。那么我会使用函数向量吗?我不认为这个问题是XY问题,因为用户先问了正确的问题,然后给出了他认为他可以做什么的可能答案。XY是当用户y问“我应该做一个切换”而没有首先说明真正的问题。
void initX() { ...; throw std::invalid_argument_exception("..."); }

int main() {
    try {
        init1(); init2(); ... run();
        return 0;
    } catch (std::exception const& e) {
        log(e.what()); exit 42;
    }
}
bool mainInit () {
  if (!system1Init ()) {
    return(false);
  }

  if (!system2Init ()) {
    return(false);
  }

  if (!system3Init ()) {
    return(false);
  }

  //...                 

  return(true);
}

//...

if(!mainInit()) {
  reportError();
}