假设我有一个带有私有变量x的c ++类。对于它的setter,使用this
有什么不同吗?是否有可能出现意外/意外行为,我不使用this
?
设置器:
void setX(double input)
{
x = input;
}
使用this
设置器:
void setX(double x)
{
this->x = x;
}
答案 0 :(得分:5)
这两个代码片段(假设它们是内联成员函数,因为没有ClassName::
位)完全等效。使用您喜欢的任何一种。我倾向于建议不要将命名参数与成员变量相同;把它们混淆起来太容易了。
答案 1 :(得分:4)
由于类模板的两阶段查找,
可能需要this
(参见第一个例子)两者都是等价的。
在非模板情况下,您通常会避免使用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
的文件,您可以在那里搜索函数名称。
答案 2 :(得分:2)
当涉及模板时,此变体会产生语法差异。但是,它在语义上是相同的; this->
变体让您更清楚地了解当前对象并避免潜在的碰撞。
答案 3 :(得分:2)
void setX(double x)
{
this->x = x;
}
如果成员变量x
被参数x
遮挡,则明确需要this->
以确保您分配正确的变量。否则就不需要了。
但我不建议你将你的论点命名为与成员变量相同的东西。你提供的第一个例子有更少的陷阱。
答案 4 :(得分:1)
它们之间没有区别。
答案 5 :(得分:1)
虽然您的代码可以运行,但代码很差,可能会让某些人感到困惑。
更好地为“setX()”参数赋予不同的名称。
e.g。
void setX(double new_x)
{
x = new_x;
}
答案 6 :(得分:0)
没关系。我使用过代码约定,声明应该通过 this 访问所有私有变量,以使代码更具可读性。但除了可读性之外,我认为没有任何区别。