如果这在C++设置程序中使用,有关系吗

Does it matter if this is used in a C++ setter?

本文关键字:有关系 程序 C++ 设置 如果      更新时间:2023-10-16

假设我有一个带有私有变量x的c++类。对于它的setter,使用this有什么区别吗?如果我不使用this,是否有可能出现不想要/意外的行为?

设置程序:

void setX(double input)
{
   x = input;
}

使用this:的设置程序

void setX(double x)
{
   this->x = x;
}

这两个代码片段(假设它们是内联成员函数,因为没有ClassName::位(完全等效。用你喜欢的。不过,我倾向于建议不要将参数命名为与成员变量相同的参数;把它们弄混太容易了。

由于类模板的两阶段查找,可能需要this

  1. 明确说明您的意思是成员
  2. 由于查找规则的原因,编译器可能会假定在那里可见的另一个实体意味着

(参见第一个示例(两者都是等效的。

在非模板情况下,通常避免使用this;生成的代码将是相同的,因此不会有任何区别(参见第二个示例(。原因是编译器会尝试查找它看到的每个符号。查找的第一个位置是类范围(块和函数范围除外(。如果它在那里找到了该名称的符号,它将隐式地发出this。实际上,成员函数只是带有不可见参数的普通函数。

class Foo {
    void foo () { x = 0; }
    void bar () const { std::cout << x; }
    void frob();
    int x;
};
void Foo::frob() {}

实际转化为

class Foo {        
    int x;
};
inline void foo (Foo *const this) { this->x = 0; }
inline void bar (Foo const * const this) { std::cout << this->x; }
void frob (Foo * const this) {}

由编译器执行。


模板中this的行为示例:

#include <iostream>
void foo() {
    std::cout << "::foo()n";
}
template <typename>
struct Base {
    void foo() const { std::cout << "Base<T>::foo()n"; }
};
template <typename T>
struct Derived_using_this : Base<Derived_using_this<T> > {
    void bar() const { this->foo(); }
};
template <typename T>
struct Derived_not_using_this : Base<Derived_not_using_this<T> > {
    void bar() const { foo(); }
};

int main () {
    Derived_not_using_this<void>().bar();
    Derived_using_this<void>().bar();
}

输出:

::foo()
Base<T>::foo()

非模板组装示例:

this:

pushq   %rbp
movq    %rsp, %rbp
subq    $16, %rsp
movq    %rdi, -8(%rbp)
movq    -8(%rbp), %rax
movl    (%rax), %eax
movl    %eax, %esi
movl    $.LC0, %edi
movl    $0, %eax
call    printf
leave
ret

this:

pushq   %rbp
movq    %rsp, %rbp
subq    $16, %rsp
movq    %rdi, -8(%rbp)
movq    -8(%rbp), %rax
movl    (%rax), %eax
movl    %eax, %esi
movl    $.LC0, %edi
movl    $0, %eax
call    printf
leave
ret

验证自己:

test.cc:

#include <stdio.h> // Don't use this. I just did so for nicer assembly.
class Foo {
public:
    Foo () : i(0) {}
    void with_this() const { printf ("%d", this->i); }
    void without_this() const { printf ("%d", i); }
private:
    int i;
};

int main () {
    Foo f;
    f.with_this();
    f.without_this();
}

运行g++ -S test.cc。您将看到一个名为test.s的文件,在那里您可以搜索函数名称。

当涉及模板时,这个变体会在语法上产生差异。然而,它在语义上是相同的;this->变体只会让您更清楚地访问当前对象,并避免潜在的冲突。

void setX(double x)
{
    this->x = x;
}

如果成员变量x会被参数x遮挡,则明确需要this->来确保您正在为正确的变量赋值。否则就不需要了。

但我不建议您将参数命名为成员变量。你举的第一个例子陷阱更少。

它们之间没有区别。

尽管您的代码可以工作,但它是糟糕的代码,可能会让人感到困惑。

给"setX(("参数一个不同的名称要好得多。

例如

void setX(double new_x)
{
   x = new_x;
}

没关系。我曾使用过代码约定,规定所有私有变量都应该通过this访问,以使代码更具可读性。但除了可读性之外,我认为没有任何区别。