使用下划线后缀对会员有益吗?

Łuk*_*Lew 25 c++ coding-style

class C {
 private:
  int member_; // here is the underscore I refer to.
}
Run Code Online (Sandbox Code Playgroud)

Google样式指南Geosoft的C++样式指南推荐使用此下划线.

我知道有不同的意见和口味.

我想问一下使用它或者被迫使用它的人是否认为它们对它们有益,中性或有害.为什么?

这是我的答案:

我理解它背后的动机,但它并不能说服我.我尝试了它,我得到的只是整个类的一点点混乱,但构造函数中的成员初始化更简单.我没有遇到下划线帮助私有成员变量和其他变量之间有所不同的情况(除了提到的初始化).

在这方面,我认为这种风格有害.

n1c*_*ckp 22

好吧,因为没有人提到它:向成员变量添加下划线允许您使用变量的"概念"名称命名getter和setter.

例如:

class MyClass
{
   int someMember_;

public:
   int someMember() const { return someMember_; }
   void someMember( int newValue ) { someMember_ = newValue; }
};
Run Code Online (Sandbox Code Playgroud)

不是我用这种风格.

  • 问题是为什么你需要getter/setter.他们对非封装的直接成员访问权的收购很少.如果你有一个低抽象,什么是类?对我来说,他们似乎是伪OO. (7认同)
  • +1.这是我使用的风格.我觉得给getter/setter命名是很方便的. (4认同)
  • 它适用于通过原始访问购买某些东西的更复杂的setter.`void someMember(int newValue){validate(newValue); someMember_ = newValue; }` (2认同)

swe*_*egi 10

我使用"m_"作为普通成员变量的前缀,使用"s_"作为静态成员变量.因此范围是直接可见的.

  • 哇,匈牙利疣! (27认同)
  • 我真的很讨厌m_惯例.成员变量过于正常,这种令人吃惊的约定往往会掩盖变量的实际名称. (8认同)
  • 我想知道一个尾随的下划线是如何因为丑陋,分散注意力而引起注意的,而领先的`m_`,更多的是一个疣(甚至没有被问过关于_),被投票了这么多沉默的人群.对理性论证这么多.`:)` (7认同)
  • 这很简单 - 你使用的是某种大型方法,而且你继承了其他人.你需要找出它的作用.如果你知道变量的范围,那就容易多了.值的局部变化比类状态的变化重要得多.这就是你需要知道范围的原因. (4认同)

sbi*_*sbi 10

如果你需要这个下划线来告诉类成员来自其他变量,你可能有太大的成员函数来立即看到什么是变量/参数.

我仍然喜欢它,因为它经常简化成员函数参数命名:

class person
{
public:
  person(const std::string& first_name, const std::string& last_name)
    : first_name_(first_name), last_name_(last_name) {}

  // .......

private:
  std::string first_name_;
  std::string last_name_;
};
Run Code Online (Sandbox Code Playgroud)

  • 实际上,您不需要构造函数的参数与成员名称不同来进行此类初始化.如果你没有使用`_`后缀,甚至`:first_name(first_name)`也可以在这里工作. (3认同)
  • 你当然可以通过将_附加到参数而不是成员来避免匈牙利疣. (2认同)
  • @digitalarbeiter:是的,我可以.但是,我必须要么总是在参数中添加一个`_`后缀(除了让我自己的约定向后退到其他人之外,我会买什么)或者由于与类的冲突而回到ad-hoc参数重命名成员(要避免的是我将_ _`附加到类成员的原因). (2认同)

And*_*ian 6

对我来说,这种装饰成员变量的好处是它适用于文本编辑器的自动完整功能.拥有前缀装饰需要您在对可以制作的内容进行实体猜测之前键入更多字符.


Tob*_*ner 5

我认为区分类变量和局部变量(如果确实需要的话还可以是全局变量)很重要。如何做并不重要——只要保持一致即可。

class Foo
{
  int mMember;
  int member_;
  int _member;
  int m_Member;
};
Run Code Online (Sandbox Code Playgroud)

所有样式都能为您提供所需的信息。只要你一直保持同样的风格,就没问题。有时其他人需要使用您的代码(例如,当您创建库或与社区合作时)。那么坚持使用 C++ 社区中最常用的样式可能是个好主意。

抱歉 - 我无法回答那是什么风格。

  • 避免使用前导下划线,在某些情况下您不应该使用它们(例如后跟大写字母),并且准确记住它们是什么真是令人头疼......而且最终太混乱了。 (7认同)
  • @JonofAllTrades:关于下划线的确切规则是:1.任何使用两个连续下划线或以下划线开头后跟大写字母的标识符都*保留给**任何范围内的实现*(`\w*__\w* ` 和 `_[AZ]\w*`)**; 2. 任何以下划线开头的标识符都*保留给**全局范围(`_\w*`)**中的实现*。我不记得确切的段落,但它在某处。 (3认同)
  • @MatthieuM:完美,谢谢。根据记录,主要讨论似乎位于http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier。 (2认同)

Rob*_*Rob 5

这基本上是一个宗教争论,所以你永远不会就这种风格达成共识。FWIW,出于其他人已经说明的原因,我将这种样式用于我的成员变量,例如:

class Foo
{
public:
  Foo(std::string name, int age) :
    name_(name),
    age_(age)
  {
  }

  std::string name() const { return name_; }
  void name(const std::string& name) { name_ = name; }

  int age() const { return age_; }
  void age(int age) { age_ = age; }
private:
  std::string name_;
  int age_;
};
Run Code Online (Sandbox Code Playgroud)

只要采用你满意的东西并坚持下去即可。