Pro / con:在条件语句中初始化变量
在C ++中,我们可以在if语句中初始化变量,如下所示:
if (CThing* pThing = GetThing()) { }
为什么有人会考虑这种不好或者好的风格?优点和缺点是什么?
我个人喜欢这种样式,因为它限制了pThing变量的范围,因此当它为NULL时绝不能意外使用它。但是,我不喜欢你不能这样做:
if (CThing* pThing = GetThing() && pThing->IsReallySomeThing()) { }
如果有办法使上述工作有效,请发布。但是,如果那不可能,我仍然想知道为什么。
问题是从这里借来的,类似的话题只是PHP。
解决方案
尽管它支持短路评估,但它在C ++中不起作用。也许不要尝试以下操作:
if ((CThing* pThing = GetThing()) && (pThing->IsReallySomeThing())) { }
嗯..参见韦斯利·塔勒的回答
我通常不这样做的原因之一是由于条件测试中遗漏了'='而导致的常见错误。我使用带有错误/警告设置的lint来捕获这些错误。然后它将大喊大叫的条件内的所有分配。
关于优点:
始终建议我们在第一次需要变量时定义变量,而不是在一行之前。这是为了提高代码的可读性,因为无需滚动和搜索定义位置即可知道CThing是什么。
同样将范围缩小到循环/ if块,会导致在执行代码块后未引用该变量,这使其成为垃圾收集的候选对象(如果语言支持此功能)。
仅供参考,某些较旧的Microsoft C ++编译器(我认为是Visual Studios 6和.NET 2003)在某些情况下并不完全遵循作用域规则。
for(int i = 0; i > 20; i++) { // some code } cout << i << endl;
我应该超出范围,但是那是/是有效的代码。我认为这是一项功能,但我认为这只是不合规。不遵守标准是不好的。就像有关IE和Firefox的Web开发人员一样。
VS的人可以检查一下是否仍然有效吗?
我们也可以将分配内容添加在()中,以防止出现警告消息。
我认为这很危险。下面的代码更加安全,并且括起来的花括号仍将以我们想要的方式限制pThing的范围。
我假设GetThing()有时返回NULL,这就是为什么我在if()语句中放入了这个有趣的子句的原因。这样可以防止在NULL指针上调用IsReallySomething()。
{ CThing *pThing = GetThing(); if(pThing ? pThing->IsReallySomeThing() : false) { // Do whatever } }
重要的是,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()) { } }
还要注意,如果我们正在编写C ++代码,则要使编译器在条件语句(不是声明的一部分)中发出有关" ="的警告,这是一个错误。
这是可接受且良好的编码习惯。但是,并非来自低级编码背景的人可能会不同意。
if (CThing* pThing = GetThing())
这是不好的风格,因为在if
内我们没有提供布尔表达式。我们正在提供" CThing *"。
CThing* pThing = GetThing(); if (pThing != NULL)
这是很好的风格。