【问题标题】:Should I use the same name for a member variable and a function parameter in C++?我应该为 C++ 中的成员变量和函数参数使用相同的名称吗?
【发布时间】:2012-05-02 06:18:09
【问题描述】:

我想知道在 C++ 中对成员变量和函数参数使用相同的名称是否是一种好习惯。

我来自 Java 背景,这很常见。我想知道在 C++ 中是否存在以下缺点(代码有效):

class Player
{
    public:
    void setState(PlayerState *state)
    {
        this->state = state;
    }

    private:
       PlayerState *state;
}

感谢您的回答。据我了解,虽然它有效,但更好的做法是放置某种标记来区分成员变量和函数参数,例如:

 _ or m_

在某些编辑器(如 Qt Designer)中,成员变量以不同的颜色显示。这就是为什么似乎没有必要添加任何前缀的原因。

【问题讨论】:

  • 纯粹是您的组织的编码准则所遵循的选择和约定。
  • 我认为除了不必写this->之外没有任何迹象。我总是在前后使用某种下划线,但这只是个人喜好问题。
  • 有些人,属性名称以m开头,例如这里是mState,如果代码被别人修改,最好这样做,你的代码越可读越好
  • 小心set/get 成员,否则您将得到quasi-classes [PDF]。
  • 我使用大写的“F”表示“字段”,但这只是历史记录。如果您使用初始化列表,则更清楚将什么分配给什么,(除非它是 C#,否则您不能)。

标签: c++ parameters naming-conventions


【解决方案1】:

这是正确的,并且是标准允许的。但更好的方法是对成员变量使用一些命名约定。例如,您可以为所有成员变量使用m_ 前缀,那么任何人都可以推断出m_state 是什么。它增加了代码的可读性,并避免了常见的错误。

另外,如果m_state是成员,那么你不必在成员函数中写this->m_state = state,你可以写m_state = state。在您当前的代码中,this-> 部分变得必要,没有它state = state 将成为自分配。

【讨论】:

  • 如果排除“this”(state=state)会发生什么?这意味着函数参数可能具有更高的优先级,因此我猜没有设置类变量!
【解决方案2】:

通常人们只是在变量后面加一个下划线,或者对函数参数使用较短的描述性较差的变量名。

我个人不喜欢同名的东西,因为读起来很容易出错。

【讨论】:

    【解决方案3】:

    我发现给成员变量与构造函数初始化参数同名是个不错的选择。

    这是我的理由:

    • 减少了标识符的数量,从而降低了复杂性
    • 你不需要发明那么多标识符
    • 如果可能的话,相同的东西应该有相同的名字,从逻辑上讲,我知道
      parameter != member
    • 上下文和索引可以允许为同一事物赋予相同的名称
    • 您可以通过搜索更轻松地找到对逻辑事物的引用(标识符), 如果所有引用都具有相同的名称

    【讨论】:

      【解决方案4】:

      C++ 和 Java 并没有什么区别,唯一的缺点是你必须输入 this->state = state 而不是 state = arg

      但是您的代码完全可以接受,它更多的是样式而不是其他任何东西。

      【讨论】:

        【解决方案5】:

        我建议您遵循一些编码风格约定。我个人使用:

        class Player
        {
            public:
            void setState(PlayerState *state)
            {
                _state = state;
            }
        
            private:
               PlayerState* _state;
        }
        

        【讨论】:

        • 我个人喜欢前面的下划线,因为它们通常用于标准库和编译器函数。我喜欢后面的下划线。
        • 我不喜欢任何下划线!使用名称修饰、__attrib 等。我已经在 C++ 中看到了足够多的下划线!
        • 所有这些都取决于您的公司所遵循的编码风格。前导下划线在许多 c# 和 java 编码风格指南中很常见 :)。
        • 如果下划线后面不跟大写字母,也可以使用前导下划线。 en.wikipedia.org/wiki/Naming_convention_(programming)
        • @AlexTheo 正式。在实践中,您会增加与前导下划线发生冲突的风险(并且您永远不会摆脱一些定义没有下划线的符号的编译器——我只是遇到了linux 的问题)。更一般地说,应该避免前导和尾随下划线,因为它们很难看到,并且使阅读代码更加困难。 myState_state 之间只有一个字符区别,而前者的可读性要好得多。
        【解决方案6】:

        这更像是一个风格问题。大多数时候, 没有问题:state 是一个非常糟糕的变量或值名称, 因为变量和值应该是限定名词,例如:

        void setState( PlayerState* newState )
        {
            currentState = newState;
        }
        

        理论上,无论如何。在实践中,我发现使用前缀很有用, 大致如下:

        class Player
        {
            PlayerState* myState;
        public:
            void setState( PlayerState* newState )
            {
                myState = newState;
            }
        };
        

        看代码的时候,如果名字以my开头,明明是一个 成员变量(如果它以our 开头,它是一个静态成员 变量)。

        还要注意,在构造函数中,您可以执行以下操作:

        Player::Player( PlayerState* state )
            : state( state )
        {
        }
        

        我不确定这对可读性有什么影响:

        Player::Player( PlayerState* initialState )
            : myState( initialState )
        {
        }
        

        看起来更清晰(但对于简单的数据持有者,区别可能 没那么重要)。

        【讨论】:

          【解决方案7】:

          请注意,如果变量遮蔽另一个变量,某些编译器 (vs 2015) 可能会生成警告。当然,可以禁用这些警告。但我认为启用这些检查是一个好习惯。

          【讨论】:

            【解决方案8】:

            没关系,事实上它甚至可能是好的形式,只要它只在你的构造函数中。

            【讨论】:

              【解决方案9】:

              这样做:

              class Player
              {
                  public:
                  void setState(PlayerState *state)
                  {
                      this->m_state = state;
                  }
              
                  private:
                     PlayerState *m_state;
              }
              

              稍后你会感谢我的。哈哈.. (:

              “m_”(“成员”)前缀将成员与函数和其他东西区分开来。对于诸如智能感知(或任何其他 IDE 自动建议)之类的东西非常有用。

              另外,如果您以后不打算更改它,请将m_state 标记为const。以防万一。

              【讨论】:

              • 制作m_stateconst表示不支持赋值。
              • @JamesKanze 它实际上取决于您将 const 关键字放在哪里 - 在类型之前、之后或星号等之后 :)
              • 鉴于m_state 有一个指针类型,唯一可以放置const 使其成为const 的位置是* 之后。否则,你不是在制造m_stateconst,而是在制造它指向const的东西。 (如果我要评论超出实际问题的内容,我会问为什么它是一个指针。PlayerState 对我来说听起来很有价值。)
              • @Poni 实际上,将const 放在类型之前或之后会导致相同的功能(可重新分配指向常量 PlayerState 的指针);在星号不同之后(指向可变 PlayerState 的常量指针)。对于这个例子来说,这些听起来都不是一个好主意。 Understanding const 是使用它的先决条件。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-10-17
              • 1970-01-01
              • 2014-01-04
              • 1970-01-01
              • 2010-12-05
              • 2010-09-21
              相关资源
              最近更新 更多