我在读c++老师的课堂笔记,他是这样写的:

使用缩进// OK 永远不要依赖运算符优先级-总是使用括号// OK 总是使用{}块-即使是单行//不可以,为什么?? Const对象在比较的左边// OK 对>= 0的变量使用unsigned,这是个不错的技巧 删除后将指针设置为NULL -双重删除保护//不错

第三种方法我不清楚:放一行进去能得到什么 A{…} ?

例如,下面这段奇怪的代码:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
    if (i % 2 == 0)
    {
        j++;
    }
}

将其替换为:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
    if (i % 2 == 0)
        j++;

使用第一个版本的好处是什么?


当前回答

为了补充之前回答中非常明智的建议,我在重构一些代码时遇到的一个例子是:我正在修改一个非常大的代码库,从一个API切换到另一个API。第一个API调用设置Company Id,如下:

setCompIds( const std::string& compId, const std::string& compSubId );

而替换需要两次调用:

setCompId( const std::string& compId );
setCompSubId( const std::string& compSubId );

我开始使用正则表达式来改变这种情况,这非常成功。我们还通过样式传递代码,这确实使它更易于阅读。然后,在审查过程中,我发现在某些条件下,它正在改变:

if ( condition )
   setCompIds( compId, compSubId );

:

if ( condition )
   setCompId( compId );
setCompSubId( compSubId );

这显然不是我们所需要的。我不得不回到一开始,再次将替换处理为完全在一个块内,然后手动修改任何最终看起来愚蠢的东西(至少它不会是不正确的)。

我注意到style现在有了一个选项——add-括号,它允许你在没有括号的地方添加括号,如果你发现自己处于和我一样的位置,我强烈建议你这样做。

其他回答

wrt 6:它更安全,因为删除空指针是一个无操作。因此,如果您碰巧两次经过这条路径,您不会因为释放空闲内存或已分配给其他内存而导致内存损坏。

这是静态文件作用域对象和单例对象的主要问题,它们没有非常明确的生命周期,并且已知它们在被销毁后会被重新创建。

在大多数情况下,您可以通过使用auto_ptrs来避免这种需要

如果你是一个编译器,这没有任何区别。两者是一样的。

但是对于程序员来说,第一个更清晰,更容易阅读,更不容易出错。

帮助防止在前面的回答中描述的错误的一个选项是内联您希望在不使用大括号时发生的事情。当您尝试修改代码时,很难不注意到错误。

if (condition) doSomething();
else doSomethingElse();

if (condition) doSomething();
    doSomething2(); // Looks pretty obviously wrong
else // doSomethingElse(); also looks pretty obviously wrong

纵观答案,没有人明确地说明了我习惯的那种实践,讲述你的代码的故事:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
    if (i % 2 == 0)
    {
        j++;
    }
}

就变成:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
    if (i % 2 == 0) j++;
}

将j++放在与if should相同的行上,向其他任何人发出信号:“我只想让这个块永远增加j”。当然,只有在行代码尽可能简单的情况下,这样做才有意义,因为在这里设置断点,正如前面提到的,并不是很有用。

事实上,我刚刚遇到了Twitter Storm API的一部分,它在Java中有这种“类型”代码。以下是执行代码的相关片段,在本幻灯片的第43页:

...
Integer Count = counts.get(word);
if (Count=null) count=0;
count++
...

for循环块中有两个东西,所以我不会内联那个代码。也就是说,从来没有:

int j = 0;
for (int i = 0 ; i < 100 ; ++i) if (i % 2 == 0) j++;

这很糟糕,我甚至不知道它是否有效(如预期的那样);不要这样做。新行和大括号有助于区分独立但相关的代码段,就像散文中的逗号或分号一样。上面的块是一个很长的句子,里面有几个从句和一些其他的语句,从来没有中断或暂停来区分不同的部分。

如果你真的想要向其他人发送一个只有一行的任务,请使用三元操作符或?:form:

for (int i = 0 ; i < 100 ; ++i) (i%2 ? 0 : >0) j++;

但这几乎是代码高尔夫,我认为这不是很好的实践(我不清楚是否应该将j++放在:的一侧)。注意,我以前没有在c++中运行过三元运算符,我不知道这是否有效,但它确实存在。

简而言之:

想象一下您的读者(即维护代码的人)如何解释您的故事(代码)。让他们尽可能清楚地知道。如果您知道新手程序员/学生正在维护这个,甚至可能留下尽可能多的{},这样他们就不会感到困惑。

我的2 c:

使用缩进

很明显

永远不要依赖运算符优先级——总是使用括号

我不会使用“从不”和“总是”这样的词,但总的来说,我认为这条规则是有用的。在某些语言(Lisp, Smalltalk)中,这不是问题。

总是使用{}块-即使是单行

我从来没有这样做过,也从来没有遇到过任何问题,但我可以看到它对学生有什么好处,特别是如果他们以前学过Python的话。

Const对象在比较的左边

尤达条件?不,请。它损害了可读性。在编译代码时使用最大警告级别即可。

对于>= 0的变量使用unsigned

好的。有趣的是,我听到斯特劳斯特鲁普不同意。

删除后将指针设置为NULL -双重删除保护

坏的建议!永远不要使用指向已删除或不存在的对象的指针。