开发者

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

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

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜