使用"this"指针而不使用它有什么区别吗?

TCS*_*TCS 11 c++ performance this

使用"this"指针是否在运行时向程序添加了另一个操作?

只是举个例子来更好地解释这个问题:

class C
{
public:
    void set_x(int val){ x = val; }
    void set_this_x(int val){ this->x = val; }

private:
    int x;
};
Run Code Online (Sandbox Code Playgroud)

在运行时,函数"C :: set_x()"执行的操作比"C :: set_this_x()"少1吗?

谢谢!:-)

In *_*ico 20

两个成员函数之间没有区别.它必须是,因为这是C++标准(ISO/IEC 14882:2003)所说的:

9.3.1非静态成员函数[class.mfct.nonstatic]

2.当一个id-expression(5.1)不属于类成员访问语法(5.2.5)并且不用于形成指向成员(5.3.1)的指针时,在类的非静态成员函数体中X使用或使用在mem-initializerfor的构造函数中X,如果名称查找(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;
};
Run Code Online (Sandbox Code Playgroud)

将根据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;
};
Run Code Online (Sandbox Code Playgroud)

为了表明确实没有区别,至少对于一个编译器,这里是对VC++编译器发出的反汇编C::set_x()C::set_this_x()函数的反对比较,禁用优化(/Od):

  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
Run Code Online (Sandbox Code Playgroud)

请注意,编译器为两个成员函数生成完全相同的程序集.


Kar*_*nek 9

不,它不会产生运行时差异,它只是语法.该this指针在第一功能还是访问,它只是规定含蓄而非明确.

顺便说一下,这有点像过早的优化 - 首先编写干净的代码,稍后编写快速的代码.


fre*_*low 6

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
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 需要一些东西来解决"x"是一个非独立名称的问题,但是某些东西不一定是"this-> x".可以在类声明中使用`using Base <int> :: x`,或者在函数`Derived :: whatever`中使用`int b = Base <int> :: x;`. (3认同)