Pro / con:在条件语句中初始化变量

时间:2008-09-25 22:18:08

标签: c++ coding-style if-statement

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

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

为什么会考虑这种糟糕或好的风格?有什么好处和坏处?

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

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

如果有办法完成上述工作,请发帖。但如果那是不可能的,我仍然想知道原因。

Question borrowed from here, similar topic but PHP.

12 个答案:

答案 0 :(得分:19)

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

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

你不能在if语句中同时使用声明和布尔逻辑,C ++语言规范特别允许表达式或声明。

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

我们如何知道a是否在表达式中的一个术语和另一个术语之间定义?

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

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

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

答案 1 :(得分:4)

关于优势:

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

同样将范围缩小为循环/ if块,导致变量在执行代码块后被取消引用,这使其成为垃圾收集的候选者(如果语言支持此功能)。

答案 2 :(得分:3)

if (CThing* pThing = GetThing())

错误的样式,因为在if内你没有提供布尔表达式。您正在提供CThing*

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

这是一种很好的风格。

答案 3 :(得分:2)

这个 应该 在C ++ 中不起作用,因为即使它支持short circuiting evaluation也许不要尝试以下方法:

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

错误..请参阅Wesley Tarle's answer

答案 4 :(得分:2)

我通常不这样做的一个原因是因为条件测试中错过了'='的常见错误。我使用带有错误/警告设置的lint来捕获它们。然后它会对条件内的所有作业大喊大叫。

答案 5 :(得分:2)

仅仅是一个FYI一些较旧的Microsoft C ++编译器(我认为Visual Studios 6和.NET 2003)在某些情况下并不完全遵循范围规则。

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

cout << i << endl;

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

有VS的人可以查看是否仍然有效吗?

答案 6 :(得分:1)

C ++ 17 起,您可以在ifswitch中包含初始化语句。

您的代码现在为:

if (CThing* pThing = GetThing(); pThing->IsReallySomeThing())
{
    // use pThing here
}
// pThing is out of scope here

答案 7 :(得分:0)

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

答案 8 :(得分:0)

我认为这有点危险。下面的代码更加安全,封闭的括号仍将以您希望的方式限制pThing的范围。

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

{
    CThing *pThing = GetThing();
    if(pThing ? pThing->IsReallySomeThing() : false)
    {
    // Do whatever
    }
}

答案 9 :(得分:0)

另请注意,如果您正在编写C ++代码,那么您希望在条件语句(这不是声明的一部分)中使编译器警告“=”错误。

答案 10 :(得分:0)

这是可以接受和良好的编码实践。但是,不是来自低级编码背景的人可能不同意。

答案 11 :(得分:0)

这么多东西。首先,裸指针。请一定避免它们。使用references,optional,unique_ptr,shared_ptr。作为最后的手段,编写自己的类来处理指针所有权,而不是别的。

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

if (CThing thing {})
{
}

确保实施operator bool以获得从CThing到bool的可预测转换。但请注意,阅读代码的其他人不会立即看到operator bool。显式方法调用通常更具可读性和令人放心。如果您可以要求C ++ 17,请使用初始化程序语法。

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

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

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