【问题标题】:Variable Naming Conventions in C++C++ 中的变量命名约定
【发布时间】:2010-09-19 02:10:24
【问题描述】:

我来自 .NET 世界,并且是编写 C++ 的新手。我只是想知道在命名局部变量和结构成员时首选的命名约定是什么。

例如,我继承的遗留代码有很多:

struct MyStruct
{
   TCHAR           szMyChar[STRING_SIZE];
   bool            bMyBool;
   unsigned long   ulMyLong;
   void*           pMyPointer;
   MyObject**      ppMyObjects;
}

来自 C# 背景的我很震惊地看到带有匈牙利符号的变量(我第一次看到 pp 前缀时就忍不住笑了)。

我更愿意以这种方式命名我的变量(尽管我不确定首字母大写是否是一个好的约定。我见过其他方式(见下面的链接)):

struct MyStruct
{
   TCHAR           MyChar[STRING_SIZE];
   bool            MyBool;
   unsigned long   MyLong;
   void*           MyPointer;
   MyObject**      MyObjects;
}

我的问题:这(前一种方式)是否仍然是在 C++ 中命名变量的首选方式?

参考资料:

http://geosoft.no/development/cppstyle.html

http://www.syntext.com/books/syntext-cpp-conventions.htm

http://ootips.org/hungarian-notation.html

谢谢!

【问题讨论】:

    标签: c++ variables naming-conventions


    【解决方案1】:

    这种匈牙利表示法相当无用,如果你必须改变某些东西的类型,可能比无用更糟糕。 (The proper kind of Hungarian Notation 是另一回事。)

    我建议您使用您的团队所做的任何事情。如果您是该程序的唯一工作人员,请以对您最有意义的方式命名。

    【讨论】:

    • 你的第二句话是完全错误的,你不应该用这种座右铭来发展。你永远不知道谁会在你之后从事这个项目。你的命名应该让你的代码对你、你的未来——你和其他人来说是明确的。变量/函数名称应该有助于理解正在发生的事情。
    • 哪里错了?如果您有任何编码经验,以对您有意义的方式命名变量让您的代码对未来的自己明确。
    【解决方案2】:

    最重要的是保持一致。如果您使用的是遗留代码库,请按照遗留代码的命名约定一致地命名变量和函数。如果您正在编写仅与旧代码交互的新代码,请在新代码中使用您的命名约定,但也要与您自己保持一致。

    【讨论】:

      【解决方案3】:

      没有。 “错误的匈牙利符号”——尤其是用于双重间接的 pp——对早期的 C 编译器来说是有意义的,你可以在其中编写

      int * i = 17;
      int j = ***i;
      

      甚至没有来自编译器的警告(甚至可能是正确硬件上的有效代码......)。

      “真正的匈牙利符号”(由 head Geek 链接)是 IMO 仍然是一个有效的选项,但不一定是首选。现代 C++ 应用程序通常有数十或数百种类型,您找不到合适的前缀。

      在一些我必须混合的情况下,我仍然在本地使用它,例如在问题域中具有非常相似甚至相同名称的整数和浮点变量,例如

      float fXmin, fXmax, fXpeak; // x values of range and where y=max
      int   iXmin, iXMax, iXpeak; // respective indices in x axis vector
      

      但是,在维护始终遵循某些约定(即使是松散的)的遗留代码时,您应该坚持其中使用的约定 - 至少在要维护的现有模块/编译单元中。

      我的推理:编码标准的目的是遵守最小意外原则。始终使用一种风格比使用哪种风格更重要。

      【讨论】:

        【解决方案4】:

        除了有点难看之外,在这个例子中,“ppMyObjects”还有什么不喜欢或嘲笑的?无论哪种方式,我都没有强烈的意见,但它确实传达了“MyObjects”所没有的有用信息。

        【讨论】:

          【解决方案5】:

          我同意这里的其他答案。为了一致性起见,要么继续使用你从传下来的风格,要么想出一个适合你团队的新约定。团队达成一致很重要,因为几乎可以保证您将更改相同的文件。话虽如此,过去我发现一些非常直观的事情:

          类/结构成员变量应该脱颖而出 - 我通常在它们前面加上 m_
          全局变量应该突出 - 通常带有 g_
          前缀 变量一般应以小写开头
          函数名一般应以大写开头
          宏和可能的枚举应该全部大写
          所有名称都应描述函数/变量的作用,而绝不应描述其类型或值。

          【讨论】:

            【解决方案6】:

            我自己是一个匈牙利符号人,因为我发现它使代码具有可读性,而且我更喜欢自我记录代码而不是 cmets 和查找。

            也就是说,我认为您可以提出一个理由来牺牲自己喜欢的风格和一些额外的可维护性以实现团队团结。为了统一的代码可读性,我不购买一致性的论点,特别是如果你为了一致性而降低可读性......它只是没有意义。不过,与你一起工作的人相处,在查看变量的类型上可能值得多混淆一些。

            【讨论】:

              【解决方案7】:

              匈牙利符号在 Win32 和 MFC API 的用户中很常见。如果您的前任正在使用它,您最好继续使用它(即使它很烂)。 C++ 世界的其他地方从来没有过这种脑残的约定,所以如果你使用的是那些 API 以外的东西,就不要使用它。

              【讨论】:

              • 匈牙利表示法在 MFC 中最为精细,但 C++ 世界的其他部分使用这种表示法的最小子集,例如 m_ 表示“成员”,p 表示“指针”。
              【解决方案8】:

              我认为您仍然会发现大多数使用 Visual C++ 编程的商店都坚持使用匈牙利表示法,或者至少是它的淡化版本。在我们的商店中,我们的应用程序有一半是旧版 C++,顶部有一个闪亮的新 C# 层(中间有一个托管 C++ 层。)我们的 C++ 代码继续使用匈牙利符号,但我们的 C# 代码使用您介绍的符号。我认为它很丑,但它是一致的。

              我说,为您的项目使用您的团队想要的任何东西。但是,如果您正在处理遗留代码或加入团队,请坚持现有的风格以保持一致性。

              【讨论】:

                【解决方案9】:

                这完全取决于个人喜好。我曾为 2 家具有类似方案的公司工作,其中成员变量被命名为 m_varName。我从未见过在工作中使用匈牙利符号,并且真的不喜欢它,但又归结为偏好。我的一般感觉是 IDE 应该注意告诉你它是什么类型,所以只要名称足以描述它的作用( m_color, m_shouldBeRenamed ),就可以了。我喜欢的另一件事是成员变量、局部变量和常量命名之间的区别,因此很容易看出函数中发生了什么以及变量来自哪里。 成员:m_varName 常量:c_varName 本地:varName

                【讨论】:

                  【解决方案10】:

                  我也更喜欢 CamelCase,事实上,我经常看到有人在 C++ 中使用 CamelCase。就个人而言,我不使用私有/受保护成员和接口的任何前缀:

                  class MyClass : public IMyInterface {
                  public:
                      unsigned int PublicMember;
                      MyClass() : PublicMember(1), _PrivateMember(0), _ProtectedMember(2) {}
                      unsigned int PrivateMember() {
                          return _PrivateMember * 1234; // some senseless calculation here
                      }
                  protected:
                      unsigned int _ProtectedMember;
                  private:
                      unsigned int _PrivateMember;
                  };
                  // ...
                  MyClass My;
                  My.PublicMember = 12345678;
                  

                  为什么我决定省略公共成员的前缀: 因为可以像在结构中一样直接访问公共成员,而不会与私有名称冲突。除了使用下划线,我还看到人们使用第一个小写字母作为成员。

                  struct IMyInterface {
                      virtual void MyVirtualMethod() = 0;
                  };
                  

                  接口包含每个定义仅需要稍后实现的纯虚拟方法。但是在大多数情况下,我更喜欢抽象类,但这是另一回事。

                  struct IMyInterfaceAsAbstract abstract {
                      virtual void MyVirtualMethod() = 0;
                      virtual void MyImplementedMethod() {}
                      unsigned int EvenAnPublicMember;
                  };
                  

                  更多灵感请见High Integrity C++ Coding Standard Manual

                  【讨论】:

                  • 我相信您的意思是说您更喜欢“Pascal”案例(我更喜欢这种情况,而且大多数 C# 开发人员都知道它是大多数人的标准,网上有大量参考资料来支持这一点)。 Camel case“myVirtualMethod”参考:“CamelCase(camel case)是一个术语,指的是编写复合词的做法,其中标识符的第一个字母小写,每个后续连接的单词的第一个字母大写。”
                  • 名称_PrivateMember 保留给编译器。
                  • @phresnel:我认为这不是真的。是的,有带有 _ 前缀的内部 C/C++ 方法,但也有带有 __ 前缀的。但是你自己的类是一种单独的命名空间,你可以随意使用任何你想要的前缀。
                  • 参见17.4.3.1.2 全局名称:某些名称集和函数签名总是保留给实现: * 每个名称包含双下划线 (_ ) 或以下划线开头后跟大写字母 (2.11) 保留给实现以供任何使用。。您的正确率是 50%:每个以下划线开头的名称都保留给实现,用作全局命名空间中的名称。
                  【解决方案11】:

                  我的团队关注这个Google C++ code convention

                  这是一个变量名示例:

                  string table_name;  // OK - uses underscore.
                  string tablename;   // OK - all lowercase.
                  
                  string tableName;   // Bad - mixed case.
                  

                  【讨论】:

                  • 为什么 tableName 不好?对我来说,它比表名更具可读性。
                  • @toddwz 因为霸主决定了。 :P
                  • 我会说tablenametableName
                  【解决方案12】:

                  如果您使用 CamelCase,则约定是首字母大写 对于类结构和非原始类型名称,数据成员的第一个字母小写。 方法的大写往往是一个混合包,我的方法往往是动词,并且已经被括号区分,所以我不将方法大写。

                  我个人不喜欢阅读 CamelCase 代码,更喜欢下划线小写 数据和方法标识符,大写类型并为首字母缩写词保留大写 以及我使用宏的罕见情况(警告这是一个宏)。

                  【讨论】:

                    猜你喜欢
                    • 2011-07-26
                    • 2011-12-21
                    • 2011-03-09
                    • 2010-09-19
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-02-17
                    相关资源
                    最近更新 更多