命名函数参数与类成员相同

时间:2013-10-18 23:39:23

标签: c++ standards

这是我在编写C ++时常常做的事情,而且我一直想知道它是一个“坏”习惯(这种行为标准化了吗?)

让我说我有一个班级:

Class Foo {
  public:
    Foo(int x) {
      //this->x is the member "x" of Foo
      //x is the paramater "x" to the function
      this->x = x; //Sets Foo::x to x (parameter x)
    }

  private:
    int x;


};

请注意Foo::Foo(int x)中的参数如何命名为x,其名称与Foo的成员变量相同。

我通常只使用use this->x = x;为成员变量赋值参数的值,这似乎对我有用(我通常使用MSVC)。在MSVC(和我认为的GCC)中,访问x将访问名为x的参数,而不是名为x成员。这是所有c ++编译器的标准化行为吗?有没有什么能阻止编译器将x与成员变量而不是参数变量相关联? (例如:this->x;等同于this->x = this->x;

4 个答案:

答案 0 :(得分:5)

是的,使用任何兼容的编译器,参数x将隐藏成员x。然而,你所写的更有趣的替代方案是:

class Foo {
public:
    Foo(int x) : x(x) {}
private:
    int x;
};

除了不可读之外,实际上会完全按照你的意愿行事。

答案 1 :(得分:5)

我同意Rob的观点,任何符合标准的编译器都会让你做你正在做的事,但你的代码很难阅读。

命名约定非常重要。选择一个命名约定,永远不要在同一个程序中改变它。

我在用C ++编程时使用本指南:http://geosoft.no/development/cppstyle.html 这是最常见的命名约定列表,每个约定都包含一个简短的声明,说明为什么选择了特定的命名约定。复制此列表并根据自己的喜好自定义。

项目#11(在命名约定下)直接解决您的问题,并为您提供更好的选择。

答案 2 :(得分:0)

虽然初始化列表可能是规范方法,但分配发生的顺序不在您的控制之下。但只需将'm_''_'添加到您的成员中即可使用一种方法。另一种方法是采用约定将'_'添加到您的参数中(如果您喜欢更清晰的成员变量声明)。像这样,

class Foo {
public:
    Foo(int _x) : x(_x), y(0) {}
    Foo(int _x,int_y) { x=_x; y=_y; }
private:
    int x, y;
};

使用它也很有效。

答案 3 :(得分:0)

实际上是回答原始查询:

我一直想知道它是否是“坏”习惯。

尽管从人类可读或支持的角度来看,兼容的编译器通常可以彼此区分,但应完全清楚哪个是最重要的。当程序员的风格不包括this->部分时,此驱动程序确实很糟糕。因此,是的,这被认为是“坏”习惯。

我使用的一种技术是在类字段的前面加上下划线。我看过其他使用标准前缀的标准,它们是TLA(三个字母的缩写)和下划线,因此不会造成任何混淆,但是对于大多数编程而言,这似乎有点过头了(除非您有大量的组合成一个可执行文件的组件,这些组件可在其他区域重复使用。

Class Foo {
  public:
    Foo(int x) {
      //this->_x is the member "x" of Foo
      //x is the paramater "x" to the function
      this->_x = x; //Sets Foo::_x to x (parameter x)
    }

  private:
    int _x;
};

我最近在宏(#define)中遇到了以下问题:

#define SET_REG_VAL(val, sys)   sys->reg = val

在代码中,我还有一个名为sys的变量。当我将代码更改为使用其他变量,但仍具有sys变量时,编译器未达到我的预期。在上面的宏中将sys更改为_sys可以解决此问题。