赞成/反对:在条件语句中初始化变量 在C++中,可以初始化if语句中的变量,如: if (CThing* pThing = GetThing()) { } 为什么人们会考虑这种坏的或好的风格?好处和坏处是什么

赞成/反对:在条件语句中初始化变量 在C++中,可以初始化if语句中的变量,如: if (CThing* pThing = GetThing()) { } 为什么人们会考虑这种坏的或好的风格?好处和坏处是什么,c++,coding-style,if-statement,C++,Coding Style,If Statement,就我个人而言,我喜欢这种风格,因为它限制了pThing变量的范围,所以当它为NULL时,永远不会意外使用它。但是,我不喜欢你不能这样做: if (CThing* pThing = GetThing() && pThing->IsReallySomeThing()) { } 如果有办法使上述工作,请张贴。但如果这不可能,我还是想知道原因 < P>此强> 强>在C++中不起作用,即使它支持。可能不要尝试以下操作: if ((CThing* pThing = GetThin

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

if (CThing* pThing = GetThing() && pThing->IsReallySomeThing())
{
}
如果有办法使上述工作,请张贴。但如果这不可能,我还是想知道原因

< P>此<>强> <>强>在C++中不起作用,即使它支持。可能不要尝试以下操作:

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

呃。。请参见

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

关于优点:

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


也将范围缩小到循环/ if块,导致变量在代码块执行之后被引用,这使得它成为垃圾收集的候选(如果语言支持这个特性)。< /P> < P>只是一些旧的微软C++编译器(Visual Studio 6和.NET 2003)的FYI。在某些情况下,不要完全遵循范围规则

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

cout << i << endl;
for(int i=0;i>20;i++){
//一些代码
}

cout您还可以在一个额外的()集合中包含此任务,以防止出现警告消息。

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

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

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

<>重要的是C++中的声明不是表达式。< /P>
bool a = (CThing* pThing = GetThing()); // not legit!!

在IF语句中不能同时声明和布尔逻辑,C++语言规范特别允许表达式或声明。< /P>

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())
    {
    }
}

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

< P>这是可接受的,并且是良好的编码实践。然而,那些没有低水平编码背景的人可能会不同意

if (CThing* pThing = GetThing())
这是糟糕的样式,因为在
if
中没有提供布尔表达式。您正在提供一个
CThing*

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

这是很好的款式。

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

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

if (CThing thing {})
{
}
确保实施
操作员bool
,以获得从CThing到bool的可预测转换。但是,请记住,其他阅读代码的人不会立即看到
操作员bool
。显式方法调用通常更具可读性和可靠性。如果需要C++17,请使用初始值设定项语法

if (CThing thing {}; thing.is_good())
{
}
如果C++17不是一个选项,请按照其他人的建议使用上面的声明

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

您可以在
if
switch
中包含初始化语句,因为C++17

您的代码现在是:

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

我试试。。。我记得我尝试过各种括号的放置方式,但都不起作用,尽管编译器的错误会因括号的不同而发生很大的变化。“短路评估”。。。到目前为止,我只知道这是“早出茅庐”。这个对我来说是新的。它是一个编译器选项,“在for语句中强制作用域”或其他什么。是的,它是/Zc:forScope—“在for循环作用域中强制一致性”。至少在VS 2008中。谢谢你们的检查。默认情况下,C++是有短路的,C++有短路评估,因此,如果“pth&& pthest->确实是某个东西”)已经保证如果pStOy是空的,就不会调用(德里克):在A中,true / false:总是被更整齐地做为“//(a *a =新a)和& ->测试()),这不是标准C++。(-1)由于技术上的冗长,我接受这个答案。关于哪个更好的讨论确实是非常主观的,我更喜欢我最初的帖子中的风格,但是我的TD不希望我使用它,所以我不喜欢。我总是可以使用一对额外的括号来限制范围,作为折衷。