开发者

Is there a difference between using "this" pointer and not using it?

开发者 https://www.devze.com 2023-03-28 01:44 出处:网络
Does using \"this\" pointer adds another operation to the program at runtime? Just to give an example to explain the question better:

Does using "this" pointer adds another operation to the program at runtime?

Just to give an example to explain the question better:

clas开发者_运维百科s C
{
public:
    void set_x(int val){ x = val; }
    void set_this_x(int val){ this->x = val; }

private:
    int x;
};

Does the function "C::set_x()", during runtime, performs 1 less operation than "C::set_this_x()" ?

Thanks! :-)


There is no difference between the two member functions. It has to be, since this is what the C++ Standard (ISO/IEC 14882:2003) has to say:

9.3.1 Nonstatic member functions [class.mfct.nonstatic]

2. When an id-expression (5.1) that is not part of a class member access syntax (5.2.5) and not used to form a pointer to member (5.3.1) is used in the body of a nonstatic member function of class X or used in the mem-initializer for a constructor of class X, if name lookup (3.4.1) resolves the name in the id-expression to a nonstatic nontype member of class X or of a base class of X, the id-expression is transformed into a class member access expression (5.2.5) using (*this) (9.3.2) as the postfix-expression to the left of the . operator. The member name then refers to the member of the object for which the function is called.

5.2.5 Class member access [expr.ref]

3. If E1 has the type “pointer to class X,” then the expression E1->E2 is converted to the equivalent form (*(E1)).E2; ...

So that means the following code:

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

would've been transformed to the following code according to 9.3.1/2 and 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;
};

To show that there really is no difference, at least for one compiler, here's a side-by-side comparison of the disassembly of the C::set_x() and C::set_this_x() function the VC++ compiler emits with optimizations disabled (/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

Note that the compiler produces the exact same assembly for both member functions.


No, it doesn't make a runtime difference, it's just syntax. The this pointer is still accessed in the first function, it's only specified implicitly instead of explicitly.

By the way, this smells like a premature optimization - write clean code first, fast code later.


The this->member syntax is required if you inherit from a class template:

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


No, there is no difference.
when you refer a member directly, the compiler actually derefers it through the this.


It's the same. However, "this" can be used to disambiguate in certain cases.

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.

If you stumbled over that expression in someone's code, it's probably originated in something like this:

struct A
{
    int x;

    void set_X(int x)
    {
        this->x = x;
    }
};


No difference, the compiler already automatically generates code for this-> While it is superfluous syntax, there are two good reasons to use it:

  • using an editor that supports auto-completion. When you type "this->", the editor pops up a tool window that presents a list of class members to choose from. This can speed up typing and helps avoid silly compile errors due to typing mistakes.

  • it helps avoiding having to come up with artificial argument names. You can give the argument the same name as the class member: void set_x(int x) { this->x = x; }.


That you can say foo instead of this->foo is just syntactic sugar. There is no difference in the compiled code. Like all syntactic sugar, a small handful decry it but most love it. To see where you stand on the issue, try using a language like perl or python that doesn't provide this syntactic sugar. Python code is peppered with self.foo; in perl OO code you'll see self->foo all over the place. It can be a bit distracting.


One of the times it matters is when you are giving a local variable the same name as a class member. For example:

class Example {

public:

    int something();
    int somethingElse();

}


int Example::somethingElse() {
    int something = something(); // ERROR
    int something = this->something(); // OK
    // ...
}
0

精彩评论

暂无评论...
验证码 换一张
取 消