如果在 C++ 中使用它是否重要?二传手?

发布于 2024-12-06 13:53:08 字数 305 浏览 1 评论 0原文

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

Setter:

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

使用 this 的 Setter:

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

Suppose I have a c++ class with a private variable, x. For it's setter, is there any difference using this? Is there the potential for unwanted / unexpected behavior is I don't use this?

Setter:

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

Setter using this:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

对岸观火 2024-12-13 13:53:08

这两个代码片段(假设它们是内联成员函数,因为没有 ClassName:: 位)完全相同。使用您喜欢的任何一个。不过,我倾向于建议不要将参数命名为与成员变量相同的名称;很容易把它们搞混。

These two code fragments (assuming they're inline member functions, since there's no ClassName:: bit) are exactly equivalent. Use whichever you prefer. I would tend to recommend against naming parameters the same as member variables though; it's too easy get them mixed up.

拿命拼未来 2024-12-13 13:53:08

由于类模板的两阶段查找,可能需要 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 的文件,您可以在其中搜索函数名称。

Because of two-phase lookup for class templates, this might be required to

  1. explicitly state you mean a member
  2. because of lookup rules, the compiler might assume another entity that is visible there is meant

(see the first example) Both are equivalent.

In a non-template situation, you usually avoid using this; the generated code will be the same, thus there won't be any difference (see the second example).
The reason for this is that the compiler will try to lookup every symbol it sees. The first place to lookup is in class-scope (except for block and function scope). If it finds a symbol of that name there, it will emit this implicitly. In reality, member functions are just ordinary functions with an invisible parameter.

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

Is actually transformed into

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) {}

by the compiler.


Behavioral example for this in templates:

#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();
}

Output:

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

Example assembly for non-template:

With 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

Without 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

Verify yourself:

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();
}

Run g++ -S test.cc. You'll see a file named test.s, there you can search for the function names.

蓝咒 2024-12-13 13:53:08

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

The this variant makes a syntactical difference when templates are involved. However, it is semantically the same; the this-> variant just makes it clearer you are accessing the current objects and avoids potential collisions.

简单爱 2024-12-13 13:53:08
void setX(double x)
{
    this->x = x;
}

如果成员变量 x 会被参数 x 遮盖,则明确需要 this-> 以确保您分配给正确的多变的。否则不需要。

但我不建议您将参数命名为与成员变量相同的名称。您给出的第一个示例的陷阱较少。

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

If the member variable x would be obscured by the argument x, then this-> is explicitly needed to ensure you are assigning to the correct variable. Otherwise it is not needed.

But I don't recommend you name your argument the same thing as a member variable anyway. The first example you give has fewer pitfalls.

夏天碎花小短裙 2024-12-13 13:53:08

它们之间没有区别。

There is no difference between them.

冷清清 2024-12-13 13:53:08

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

最好给“setX()”参数一个不同的名称。

例如

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

Although your code will work, it is poor code and likely to confuse somebody.

Much better to give the "setX()" parameter a different name.

e.g.

void setX(double new_x)
{
   x = new_x;
}
少女的英雄梦 2024-12-13 13:53:08

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

Doesn't matter. I've worked with code conventions stating that all private vars should be accessed through this in order to make the code more readable. But other than readability I don't think there is any difference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文