使用指针和不使用指针"this"有区别吗?
Is there a difference between using "this" pointer and not using it?
是否使用"this"指针在运行时为程序增加了另一个操作?
只是为了更好地解释这个问题:
class C
{
public:
void set_x(int val){ x = val; }
void set_this_x(int val){ this->x = val; }
private:
int x;
};
函数"C::set_x()"在运行时比"C::set_this_x()"少执行1次操作吗?
?谢谢!: -)
这两个成员函数没有区别。它必须是,因为这是c++标准(ISO/IEC 14882:2003)必须说的:
9.3.1非静态成员函数[class.mfct.nonstatic]2。当
id-expression
(5.1)不是类成员的一部分时访问语法(5.2.5),不能用于形成指向成员的指针(5.3.1)。在类X
或?的非静态成员函数体中使用mem-initializer
中用于X
类的构造函数,如果名称lookup(3.4.1)将id-expression
中的名称解析为非静态的类X
或X
基类的非类型成员id-expression
被转换为类成员访问表达式(5.2.5)使用(*this)
(9.3.2)作为左侧的后缀表达式.
操作符。类的成员对象。5.2.5类成员访问(expr.ref)
3。如果
E1
的类型是"指向类X
的指针",则表达式E1->E2
被转换成等价形式(*(E1)).E2;
…
这意味着下面的代码:
class C
{
public:
void set_x(int val) { x = val; }
void set_this_x(int val) { this->x = val; }
private:
int x;
};
将根据9.3.1/2和5.2.5/3转换为以下代码:
class C
{
public:
void set_x(int val) { (*this).x = val; } // as per 9.3.1/2
void set_this_x(int val) { (*(this)).x = val; } // as per 5.2.5/3
private:
int x;
};
为了表明它们之间没有区别,至少对于一个编译器来说,下面是vc++编译器在禁用优化(/Od
)的情况下对C::set_x()
和C::set_this_x()
函数的反汇编的并排比较:
void set_x(int val){ x = val; } void set_this_x(int val){ this->x = val; }
push ebp push ebp
mov ebp,esp mov ebp,esp
sub esp,0CCh sub esp,0CCh
push ebx push ebx
push esi push esi
push edi push edi
push ecx push ecx
lea edi,[ebp-0CCh] lea edi,[ebp-0CCh]
mov ecx,33h mov ecx,33h
mov eax,0CCCCCCCCh mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi] rep stos dword ptr es:[edi]
pop ecx pop ecx
mov dword ptr [ebp-8],ecx mov dword ptr [ebp-8],ecx
mov eax,dword ptr [this] mov eax,dword ptr [this]
mov ecx,dword ptr [val] mov ecx,dword ptr [val]
mov dword ptr [eax],ecx mov dword ptr [eax],ecx
pop edi pop edi
pop esi pop esi
pop ebx pop ebx
mov esp,ebp mov esp,ebp
pop ebp pop ebp
ret 4 ret 4
注意,编译器为两个成员函数生成了完全相同的程序集。
不,这不会造成运行时差异,只是语法不同。this
指针仍然在第一个函数中被访问,它只是隐式地指定,而不是显式地指定。
顺便说一下,这听起来像是一个过早的优化——先写干净的代码,再写快速的代码。
如果从类模板继承,则需要this->member
语法:
template<typename T>
class Base
{
protected:
T x;
};
template<typename T>
class Derived : Base<T>
{
public:
void whatever()
{
T a = x; // error
T b = this->x; // ok
}
};
不,没有区别。
当你直接引用一个成员时,编译器实际上是通过this
来解引用它。
是一样的。然而,在某些情况下,"this"可以用来消除歧义。
class C
{
public:
void set_x(int x){ x = x; } // does nothing
void set_this_x(int x){ this->x = x; } // sets the variable
private:
int x;
};
No。
如果你在别人的代码中偶然发现了这个表达式,它很可能起源于这样的地方:
struct A
{
int x;
void set_X(int x)
{
this->x = x;
}
};
没有区别,编译器已经自动为此生成代码->虽然它是多余的语法,但有两个很好的理由使用它:
-
使用支持自动完成的编辑器。当您输入"this->"时,编辑器会弹出一个工具窗口,显示可供选择的类成员列表。这可以加快输入速度,并有助于避免由于输入错误而导致的愚蠢的编译错误。
-
它有助于避免不得不提出人为的参数名称。你可以给实参赋予与类成员相同的名称:void set_x(int x) {this->x = x;} .
你可以说foo
而不是this->foo
只是语法上的糖。编译后的代码没有区别。像所有语法糖一样,一小部分人谴责它,但大多数人喜欢它。要了解您在这个问题上的立场,请尝试使用不提供这种语法糖的语言,如perl或python。Python代码中充斥着self.foo
;在perl OO代码中,您将看到到处都是self->foo
。它可能会让人分心。
当您为局部变量赋予与类成员相同的名称时,这一点很重要。例如:
class Example {
public:
int something();
int somethingElse();
}
int Example::somethingElse() {
int something = something(); // ERROR
int something = this->something(); // OK
// ...
}
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在C++中释放内存期间,迭代器与指针有何不同
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- 指针投射:指针有价值吗?
- 指向数组基址的指针而不是指向第一个元素的指针有什么优点?
- 在以下声明中使用指针有什么区别?
- C 中的通用指针和 C++ 中的通用指针有什么区别?
- 带"new"的指针和带"&variable"的指针有什么区别
- Boost 智能指针和 std 智能指针有什么区别?
- 数组的名称和指向第一个元素的另一个指针有什么区别
- 定义 char 和 int 时指针有什么区别
- std::thread constructor传递指针和通过引用传递有区别吗
- 这些存储指针数组的方法之间有区别吗
- c++中的自动指针和共享指针有什么区别?
- .get() 和 -> 之间有智能指针的区别吗?
- 在C++中,char 数组的名称和 char 指针有什么区别?
- c#中的委托和c++中的函数指针有什么区别
- 指针和分配了内存的指针有什么区别
- 使用指针和不使用指针"this"有区别吗?
- 全局指针和本地指针有什么区别?