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

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

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

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

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

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

从这里借来的问题,与PHP类似的主题。

有帮助吗?

解决方案

重要的是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())
    {
    }
}

其他提示

关于优势:

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

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

if (CThing* pThing = GetThing())

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

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

这是一种很好的风格。

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

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

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

cout << i << endl;

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

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

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

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

错误..请参阅 Wesley Tarle的回答

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

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

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

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

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

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

这么多东西。首先,裸指针。请一定避免它们。使用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())
  {
  }
}
scroll top