代码之家  ›  专栏  ›  技术社区  ›  steffenj

赞成/反对:在条件语句中初始化变量

  •  16
  • steffenj  · 技术社区  · 18 年前

    在C++中,可以初始化if语句中的变量,如下所示:

    if (CThing* pThing = GetThing())
    {
    }
    

    为什么人们会考虑这种坏的或好的风格?好处和坏处是什么?

    就我个人而言,我喜欢这种风格,因为它限制了pThing变量的范围,所以当它为NULL时,永远不会意外使用它。但是,我不喜欢你不能这样做:

    if (CThing* pThing = GetThing() && pThing->IsReallySomeThing())
    {
    }
    

    如果有办法使上述工作,请张贴。但如果这不可能,我还是想知道原因。

    Question borrowed from here, similar topic but PHP.

    11 回复  |  直到 9 年前
        1
  •  20
  •   Wesley Tarle    18 年前

    重要的是C++中的声明不是表达式。

    bool a = (CThing* pThing = GetThing()); // not legit!!
    

    if(A *a = new A)
    {
        // this is legit and a is scoped here
    }
    

    if((A *a = new A) && a->test())
    {
        // was a really declared before a->test?
    }
    

    咬紧牙关,使用内部if。范围规则非常有用,并且您的逻辑非常明确:

    if (CThing* pThing = GetThing())
    {
        if(pThing->IsReallySomeThing())
        {
        }
    }
    
        2
  •  4
  •   Pablo Fernandez    18 年前

    关于优势:

    总是建议在您第一次需要变量时定义变量,而不是之前的一行。这是为了提高代码的可读性,因为不必滚动和搜索CThing的定义位置,就可以知道CThing是什么。

    同时,将作用域缩小到循环/if块,会导致变量在代码块执行后不被引用,这使得它成为垃圾收集的候选对象(如果语言支持此功能)。

        3
  •  3
  •   Daniel Daranas    16 年前
    if (CThing* pThing = GetThing())
    

    它是 不良风格 ,因为在 if 您没有提供布尔表达式。您正在提供一个 CThing* .

    CThing* pThing = GetThing();
    if (pThing != NULL)
    

        4
  •  2
  •   Steve Fallows    18 年前

    我通常不这样做的一个原因是因为在条件测试中缺少“=”的常见错误。我使用设置了错误/警告的lint来捕捉这些错误/警告。然后,它会在条件语句中对所有赋值进行叫喊。

        5
  •  2
  •   J.J.    18 年前

    只是FYI一些旧的微软C++编译器(Visual Studio 6和.NET 2003)在一些情况下不太符合范围规则。

    for(int i = 0; i > 20; i++) {
         // some code
    }
    
    cout << i << endl;
    

    我应该在范围之外,但那是/是有效代码。我相信它是作为一个功能来播放的,但在我看来,这只是不合规。不遵守标准是不好的。就像一个关于IE和Firefox的网络开发者一样。

    有VS的人能检查一下这是否仍然有效吗?

        6
  •  2
  •   Community Mohan Dere    9 年前

    这 应该 在C++中不起作用 自从 short circuiting evaluation . 大概

    if ((CThing* pThing = GetThing()) && (pThing->IsReallySomeThing()))
    {
    }
    

    犯错误看见 Wesley Tarle's answer

        7
  •  2
  •   proski    8 年前

    很多事情。首先,简单的指针。请尽量避免它们。使用引用、可选、唯一\u ptr、共享\u ptr。作为最后的手段,编写自己的类来处理指针所有权而不是其他。

    如果需要C++11,请使用统一初始化(最好使用C++14以避免C++11缺陷):-它避免了=vs==混淆,并且在检查参数时更严格。

    if (CThing thing {})
    {
    }
    

    确保实施 operator bool 以获得从CThing到bool的可预测转换。但是,请记住,阅读代码的其他人不会看到 接线员布尔 马上显式方法调用通常更具可读性和可靠性。如果需要C++17,请使用初始值设定项语法。

    if (CThing thing {}; thing.is_good())
    {
    }
    

    如果C++17不是一个选项,请按照其他人的建议使用上面的声明。

    {
      CThing thing {};
      if (thing.is_good())
      {
      }
    }
    
        8
  •  1
  •   Roman2452809    7 年前

    您可以在其中包含初始化语句 if 和 switch C++17 .

    if (CThing* pThing = GetThing(); pThing->IsReallySomeThing())
    {
        // use pThing here
    }
    // pThing is out of scope here
    
        9
  •  0
  •   Martin Beckett    18 年前

    您还可以将分配包含在一组额外的()中,以防止出现警告消息。

        10
  •  0
  •   Adam Pierce    18 年前

    我认为这有点危险。下面的代码要安全得多,括号仍然会以您想要的方式限制pThing的范围。

    我假设GetThing()有时返回NULL,这就是为什么我在if()语句中放了那个有趣的子句。它防止对空指针调用IsReallySomething()。

    {
        CThing *pThing = GetThing();
        if(pThing ? pThing->IsReallySomeThing() : false)
        {
        // Do whatever
        }
    }
    
        11
  •  0
  •   Wesley Tarle    18 年前

        12
  •  0
  •   ilitirit    18 年前