14

我最近花了很多时间在 javascript 上,现在又回到了 C++。当我从一个方法访问一个类成员时,我倾向于在它前面加上this->.

class Foo {

  int _bar;

public:  
  /* ... */

  void setBar(int bar) {
    this->_bar = bar;
    // as opposed to
    _bar = bar;
  }
}

在阅读时,当我试图弄清楚它来自哪里时,它为我节省了一个大脑循环。
有什么理由我不应该这样做吗?

4

8 回答 8

13

将 this-> 用于类变量是完全可以接受的。

但是,不要以下划线开头的标识符,或在任何__地方包含任何带有双下划线的标识符。如果您违反这两个经验法则中的任何一个,则某些类别的保留符号很容易被击中。(特别是,_IdentifierStartingWithACapital 由编译器标准保留)。

于 2012-11-13T20:08:11.953 回答
10

原则上,通过访问成员this->是一种有助于使事情更清晰的编码风格,但这似乎是一个品味问题。

但是,您似乎也使用带有_(下划线)的前缀成员。我会说这太多了,你应该选择两种风格中的任何一种。

于 2012-11-13T20:08:28.793 回答
7

有什么理由我不应该这样做吗?

是的,你不应该这样做是有原因的。

this->仅当名称被隐藏时才严格要求引用成员变量,例如:

class Foo
{
public:
    void bang(int val);
    int val;
};

void Foo::bang(int val)
{
    val = val;
}

int main()
{
    Foo foo;
    foo.val = 42;
    foo.bang(84);
    cout << foo.val;

}

该程序的输出是42, not 84,因为在bang成员变量中已被隐藏,并val = val导致无操作。在这种情况下,this->需要:

void Foo::bang(int val)
{
    this->val = val;
}

在其他情况下,使用this->没有效果,因此不需要。

这本身并不是不使用this->. 然而,这样一个程序的维护是不使用的一个理由this->

您正在使用this->作为文档的一种方式来指定后面的变量是成员变量。然而,对于大多数程序员来说,这并不是 usignthis->实际记录的内容。使用this->文件是:

这里隐藏了一个名字,所以我正在使用一种特殊的技术来解决这个问题。

由于这不是您想要传达的内容,因此您的文档已损坏。

与其this->用来记录名称是成员变量,不如始终使用合理的命名方案,其中成员变量和方法参数永远不会相同。

编辑 考虑相同想法的另一个插图。

假设在我的代码库中,你发现了这个:

int main()
{
    int(*fn)(int) = pingpong;
    (fn)(42);
}

相当不寻常的构造,但作为一个熟练的 C++ 程序员,你会看到这里发生了什么。 fn是一个指向函数的指针,并且被分配了 的值pingpong,不管它是什么。pingpong然后用单int值调用指向的函数42。所以,想知道为什么你需要这样一个小发明,你去寻找pingpong并找到这个:

static int(*pingpong)(int) = bangbang;

好的,那是什么bangbang

int bangbang(int val)
{
    cout << val;
    return val+1;
}

“现在,等一下。这到底是怎么回事?为什么我们需要创建一个指向函数的指针,然后通过它调用?为什么不直接调用函数?这不一样吗?”

int main()
{
    bangbang(42);
}

是的,它是一样的。观察到的效果是一样的。

想知道这是否真的只有它,你会看到:

/*  IMPLEMENTATION NOTE
 *
 *  I use pointers-to-function to call free functions
 *  to document the difference between free functions
 *  and member functions.
 */

所以我们使用指向函数的唯一原因是为了表明被调用的函数是一个自由函数而不是一个成员函数。

对你来说,这似乎只是一个“风格问题”吗?因为这对我来说似乎很疯狂。

于 2012-11-13T21:27:29.197 回答
4

在这里你会发现:

除非隐藏类成员名称,否则使用类成员名称等同于使用带有 this 指针和类成员访问运算符 (->) 的类成员名称。

于 2012-11-13T20:10:55.257 回答
4

我认为你这样做是倒退的。您希望代码向您保证所发生的事情正是预期的。

为什么要添加额外的代码来指出没有发生什么特别的事情?在成员函数中访问类成员一直在发生。这就是预期的结果。当不是正常的事情发生时,添加额外的信息会更好。

在这样的代码中

class Foo
{
 public:
    void setBar(int NewBar) 
    { Bar = NewBar; }

你问自己 - “Bar从哪里来?”。

由于这是类中的设置器,如果不是类成员变量,它会设置什么?!如果不是,那么就有理由添加很多关于这里实际发生的事情的信息!

于 2012-11-13T21:53:40.670 回答
3

由于您已经在使用约定来表示标识符是数据成员(尽管我不建议这样做),因此添加this->几乎在所有情况下都是多余的。

于 2012-11-13T20:12:52.647 回答
3

这显然是一个有点主观的问题。this->似乎比 C++ 惯用的 Python 惯用得多。在 C++ 中只有少数情况this->需要前导,处理父模板类中的名称。一般来说,如果您的代码组织良好,那么读者会很明显它是成员变量或局部变量(应该避免使用全局变量),并且减少要读取的数量可能会降低复杂性。此外,您可以使用可选样式(我喜欢尾随_)来指示成员变量。

于 2012-11-13T20:25:38.520 回答
2

它实际上并没有伤害任何东西,但是有 OO 经验的程序员会看到它并觉得很奇怪。看到“尤达条件句”同样令人惊讶,即if (0 == x).

于 2012-11-13T20:07:21.773 回答