为什么人们不缩进 C++访问说明符/case 语句?

发布于 2024-10-05 02:02:09 字数 1432 浏览 3 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

划一舟意中人 2024-10-12 02:02:09

增加缩进通常反映进入新的嵌套范围,而访问说明符和 switch case 语句不会改变范围(通常标签也是如此)。访问说明符可以是可选的,因为您可以开始实现一个类或结构,并且所有成员只需要隐式访问(即分别为私有和公共),但随后代码演变,您需要为非隐式访问添加说明符访问成员:真的值得突然更改所有成员的缩进吗?同样,没有嵌套范围,所以我认为这会产生误导。

如果您在固定宽度的终端上工作并相应地换行,则重新缩进会很痛苦。但是,让访问说明符从成员中脱颖而出是很有用的,这意味着将它们放回左侧的某个位置 - 要么与 class 关键字一致,要么在其中的一部分。

就我个人而言,我这样做:

class X
{
  public:
    int member_function()
    {
        switch (expression)
        {
          case X:
            return 6;

          default:
          {
            int n = get_value() / 6;
            return n * n;
          }
        }
    }

  private:
    int member_variable_;
};

为什么我不进一步缩进每个 case 的代码?我不能声称我所做的事情特别合乎逻辑,但因素包括:

  • 我不想弱化一般的 switch/case 缩进,因为它直观地传达了这个开关对于快速理解代码很重要,
  • 我很高兴将 {} 放在现有 case 代码周围 - 更像是注释“嘿,我需要一个范围” - 而不是感觉被迫进一步缩进所有内容,这甚至对我来说也没有多大意义,但感觉不错 - 我喜欢为每个 case 行编写代码 我
  • 如果您在 case 语句中引入新变量而不引入作用域,一些编译器会发出警告,即使不存在稍后使用该变量可能未初始化的情况,
  • 通常是一个 80 列编码器,通常有 4 个空格缩进,因此位于 switch 内 - 因此显然是一个函数 - 意味着剩余的列是有价值的。

对于 class/struct 也是如此:

  • 我想扫描左列并快速找到类的末尾,或者轻松地在屏幕上或打印输出中计算小类;完全相同的缩进级别的访问说明符不再强调 class 关键字,但它确实有助于使它们在视觉上与成员不同(如果类/结构超过几行,我还添加一个空白预先行)
  • 当我引入 privateprotected 说明符时,我不想更改现有的 class/struct 成员缩进

结论:很多一些小因素会影响人们的缩进偏好,如果你想在企业环境中成为一名 C++ 程序员(尤其是承包商),你只需要顺其自然,有时也能够改变自己的风格(例如,我是现在陷入了camelCaseLand,公共成员变量以大写字母开头 - 哎呀!)。别担心——这不值得。

Increasing indentation normally reflects entry to a new nested scope, whereas both access specifiers and switch case statements don't vary the scope (the same is true of labels generally). Access specifiers can be optional in that you may start implementing a class or struct and have all members only need the implied access (i.e. private and public respectively), but then the code evolves and you need to add a specifier for the non-implied-access members: is it really worth having to suddenly change the indentation on all members? Again, there's no nested scope, so I think that would be actively misleading.

If you work on fixed-width terminals and wrap your lines accordingly, reindenting's a pain. But, it is useful to have the access specifiers stand out from the members, which means putting them back to the left somewhere - either in line with the class keyword or part-way there.

Personally, I do this:

class X
{
  public:
    int member_function()
    {
        switch (expression)
        {
          case X:
            return 6;

          default:
          {
            int n = get_value() / 6;
            return n * n;
          }
        }
    }

  private:
    int member_variable_;
};

Why do I not indent code for each case further? I can't claim what I do is particularly logical, but factors include:

  • I don't want to deemphasise the general switch/case indentation, as visually communicating the extent of the switch is important to quickly understanding the code
  • I'm happy just to put the { and } around existing case code - more like a comment "hey, I need a scope" - rather than feeling compelling to indent everything further, which doesn't make much sense even to me but kind of feels right - I like having the code for each case line up
  • some compilers do warn if you introduce new variables inside a case statement without introducing a scope, even if there are no cases when the variable is later used potentially uninitialised
  • I'm an 80-column coder generally, with 4 space indents normally, so being inside a switch - and thus obviously a function - means remaining columns are valuable.

Same for class/struct:

  • I want to scan the left column and quickly find the end of the class, or easily count the small classes on screen or in a printout; access specifiers at exactly the same indentation level deemphasise the class keyword, but it does help to have them visually distinct from the members (if the class/struct is more than a few lines, I also add a blank line beforehand)
  • I don't want to change existing class/struct member indentation when I introduce a private or protected specifier

In conclusion: lots of small factors go into developing people's indentation preferences, and if you want to be a C++ programmer in a corporate environment - especially a contractor - you just have to go with the flow and be able to change your own style sometimes too (e.g. I'm stuck in camelCaseLand right now, with public member variables starting with an uppercase letter - yikes!). Don't sweat it - it's not worth it.

恋竹姑娘 2024-10-12 02:02:09

访问说明符实际上只是标签(如 goto 使用的标签)。人们通常不会缩进标签,或者相对于周围的代码将它们缩进一级。所以我想说这根本不矛盾。

标准也使用这种样式作为访问说明符。第 10 章第 2 段的示例:

class Base {
public:
  int a, b, c;
};

The access specifiers are really just labels (as in those used by goto). People generally don't indent labels, or outdent them one level with respect to the surrounding code. So I would say this is not inconsistent at all.

The Standard also uses this style for access specifiers. Example from Chapter 10, paragraph 2:

class Base {
public:
  int a, b, c;
};
拿命拼未来 2024-10-12 02:02:09

想象这样一个类定义:

class SomeClass {
    void ImplicitlyPrivateMethod();
public:
    void someMethod();
private:
    int someMember;
};

使用您提出的缩进样式,需要将其更改为

class SomeClass {
        void ImplicitlyPrivateMethod();
    public:
        void someMethod();
    private:
        int someMember;
};

(这对很多人来说看起来不太好,特别是如果“隐式”部分足够长)。


我个人更喜欢此类说明符的半缩进:

class SomeClass {
    void ImplicitlyPrivateMethod();
  public:
    void someMethod();
  private:
    int someMember;
};

但这是个人品味的问题。

Imagine such a class definition:

class SomeClass {
    void ImplicitlyPrivateMethod();
public:
    void someMethod();
private:
    int someMember;
};

With the style of indentation you propose, one would need to change this into

class SomeClass {
        void ImplicitlyPrivateMethod();
    public:
        void someMethod();
    private:
        int someMember;
};

(which looks not so nice to many people, especially if the "implicit" section is long enough).


I personally prefer half-indentation of such specifiers:

class SomeClass {
    void ImplicitlyPrivateMethod();
  public:
    void someMethod();
  private:
    int someMember;
};

But this is a matter of personal taste.

念﹏祤嫣 2024-10-12 02:02:09

与许多其他事情一样,重要的是不要将规则与目的混淆。缩进的目的是通过提供关于内容所属位置的额外视觉提示,使代码更清晰、更易于阅读。现在,在您提到的特定情况下,与命名空间一起,在许多情况下,额外的缩进对可读性没有帮助。 switch 中的 case 可以理解为 if-else,其中您不会添加额外的缩进。这些大小写是类似于花括号的块分隔符

switch ( var ) {  
case 1:          // if ( var == 1 ) {
   code;
   break;        // }
case 2:          // else if ( var == 2 ) {
   code;
   break;        // }
}

在类级别,访问修饰符可以被视为与类大括号处于同一级别的块分隔符。添加额外的缩进并不会使代码更清晰:

class test {
public:
   void foo();
private:
   int member;
};

命名空间也是如此,有些人避免缩进整个命名空间级别。在这三种情况下,添加额外的缩进并没有明显的优势,如果您遵守短代码行(80/100 个字符)和足够大的缩进级别(8 甚至 4 个字符),那么不缩进可能会有优势。

就我个人而言,我从不缩进 case 或访问器修饰符,在 namespace 的情况下,它取决于......覆盖整个源代码的 namespace文件很可能不会缩进,而仅包含源文件一部分的命名空间将被缩进——其基本原理是,在前一种情况下,它不会添加实际值,而在第二种情况下,它会添加实际值。

As with many other things, it is important not to mistake the rule with the purpose. The purpose of indentation is making code clearer and easier to read by providing an extra visual hint on what belongs where. Now, in the particular cases you mention, together with namespaces, in many cases the extra indentation does not help in readability. The cases in a switch can be understood as if-elses, where you would not add the extra indentation. The cases are block delimiters similar to the curly braces.

switch ( var ) {  
case 1:          // if ( var == 1 ) {
   code;
   break;        // }
case 2:          // else if ( var == 2 ) {
   code;
   break;        // }
}

At class level, access modifiers can be considered to be block delimiters at the same level that the class braces. Adding an extra level of indentation does not make the code clearer:

class test {
public:
   void foo();
private:
   int member;
};

The same way goes with namespaces, where some people avoid indenting the whole namespace level. In all three cases, there is no clear advantage in adding the extra indentation and if you abide to short code lines (80/100 characters) and big enough indentation levels (8 or even 4 characters) then there might be an advantage to not indenting.

Personally, I never indent case or accessor modifiers, in the case of namespaces, it depends... a namespace that covers the whole source file will most probably not be indented, while namespaces that only take part of the source file will be indented --the rationale is that in the former case it adds no actual value, while in the second it does.

情未る 2024-10-12 02:02:09

两个可能的原因:

  • 这就是 Bjarne Stroustrup 在他的书中缩进的方式

  • 大多数文本编辑器自动以这种方式缩进

Two possible reasons:

  • that's how Bjarne Stroustrup indents them in his books

  • most text editors indent them that way automatically

吾家有女初长成 2024-10-12 02:02:09

因为 publicprivate 是不引入新范围的标签,所以我不喜欢给它们任何特殊的缩进,因此:

class foo {
    public:
    void something();
    void something_else();

    private:
    int top_secret;
};

这样,一致的缩进规则是“缩进等于范围”。

Because public and private are labels which don't introduce a new scope, I prefer not to give them any special indentation, thus:

class foo {
    public:
    void something();
    void something_else();

    private:
    int top_secret;
};

This way, the consistent indentation rule is "indentation equals scope".

我不吻晚风 2024-10-12 02:02:09

这都是关于分支的范围和分组。如果这些不受影响,则不要添加缩进级别。

以以下情况为例:

if( test == 1 ) {
    action1( );
} else if( test == 2 ) {
    action2( );
} else {
    action3( );
}

记下语句块的级别。现在将其重写为带有缩进大小写的 case 语句:

switch( test ) {
    case 1:
        action1( );
        break;
    case 2:
        action2( );
        break;
    default:
        action3( );
        break;
}

这在功能上完全相同,但缩进与我的操作不匹配。我认为正是这种不一致最终让我放弃了额外的虚假缩进。 (尽管我不介意其他人提出的半缩进,但请注意。)

It's all about scoping and grouping of branches. If these are not affected, then do not add an indentation level.

Take for instance the following:

if( test == 1 ) {
    action1( );
} else if( test == 2 ) {
    action2( );
} else {
    action3( );
}

Take note of the levels of the statement blocks. Now re-write it as a case statement with indented cases:

switch( test ) {
    case 1:
        action1( );
        break;
    case 2:
        action2( );
        break;
    default:
        action3( );
        break;
}

This does the exact same functionally, yet the indentations don't match of my actions. And I think it is this inconsistency that finally made me change to dropping the extra spurious indentation. (Even though I don't mind the half-indenting proposed by others, mind you.)

林空鹿饮溪 2024-10-12 02:02:09

每个类的访问修饰符行很少,并且大多数编辑器的颜色修饰符与其他所有内容都不同。它们本身就很引人注目,因此无需添加选项卡。

There are very few access modifier lines per class, and most editors color modifiers differently from everything else. They stand out plenty on their own, so adding tabs is unnecessary.

何处潇湘 2024-10-12 02:02:09

如前所述(尽管主张非缩进访问修饰符),访问修饰符形成逻辑块。虽然它们与类大括号处于同一级别,但它们很特殊。

因此,使用缩进来清楚地显示每个块的开始和结束位置非常有用。

我个人认为这样可以让代码更加清晰。其他人会不同意。

这是一个比较主观的问题。

As mentioned earlier (though argued for non-indented access modifiers), access modifiers form logical blocks. While these are at the same level as the class braces, they are special.

Thus it's useful to have indentation to clearly show where each block starts and ends.

I personally think it makes the code clearer. Others will dissagree.

This is a rather subjective question.

灯角 2024-10-12 02:02:09

大多数编辑器都会自动缩进它们。对我来说,我将它们保留在小类或小文件或短 switch 语句中,但对于长文件或包含许多长 switch 语句的长文件,我使用更多缩进以便于阅读。

我有时会这样做,我觉得这是旧风格:

Class CClass
    {
            CClass();
            ~CClass();
        Public:
            int a;
        Private:
            int b;
     };
CClass::CClass
      {
           TODO code;
      }

当文件可能包含超过 20 或 50 个函数时,这有时会更容易,因此您可以轻松找到每个函数的开头。

Most editors indent them automatically. For me, I leave them as they are in small classes or small files or short switch statements, but for long ones or a long file with many long switch statements I use more indentation for easier readability.

I sometimes do this which I feel is as old style:

Class CClass
    {
            CClass();
            ~CClass();
        Public:
            int a;
        Private:
            int b;
     };
CClass::CClass
      {
           TODO code;
      }

This sometimes makes it easier when a file may contain more than 20 or 50 functions, so you can easily spot the beginning of every function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文