tags:

views:

600

answers:

12

When should I explicitly write this->member in a method of a class?

A: 

Ok, after reading the comment I think I understand the problem. I was thinking the question was whenever to access member field or method via "this" we have to use -> operator. Probably I misunderstand the question, but the answer wasn't totally incorrect, you may to use it always in order to avoid ambiguity, but in general case you need it to explicitly refer to right scope of variable of instance of the class which "this" is pointing.

Artem Barger
This is just wrong, you don't always have to put this-> before anything.
GMan
Can you explain yourself more detailed, since you've downvoted me twice on same answer?
Artem Barger
I've seen java guys do this when writing C++...but no, "this->" is assumed when referencing members of the same class.
DarkSquid
This answer is just wrong.
PaV
@DarkSquid, not the class but instance.
Artem Barger
For the record I didn't downvote you. Perhaps you are misunderstanding the question. Maybe you think he's asking when to use the -> operator?
GMan
Yes, you are correct.
Artem Barger
+9  A: 

If you declare a local variable in a method with the same name as an existing member, you will have to use this->var to access the class member instead of the local variable.

#include <iostream>
using namespace std;
class A
{
    public:
        int a;

        void f() {
            a = 4;
            int a = 5;
            cout << a << endl;
            cout << this->a << endl;
        }
};

int main()
{
    A a;
    a.f();
}

prints:

5
4

PaV
+1 for the scope clarification corner case
DarkSquid
I would better use cout << A::a << endl; instead. ``this" is unimportant in this case.
siddhant3s
I would rather just avoid the name clash with conventions like "m_a" or "a_".
Tom
+1  A: 

You need to use this to disambiguate between a parameters/local variables and member variables.

class Foo
{
protected:
  int myX;

public:
  Foo(int myX)
  {
    this->myX = myX; 
  }
};
Brian R. Bondy
+1  A: 

You only have to use this-> if you have a symbol with the same name in two potential namespaces. Take for example:

class A {
public:
   void setMyVar(int);
   void doStuff();

private:
   int myVar;
}

void A::setMyVar(int myVar)
{
  this->myVar = myVar;  // <- Interesting point in the code
}

void A::doStuff()
{
  int myVar = ::calculateSomething();
  this->myVar = myVar; // <- Interesting point in the code
}

At the interesting points in the code, referring to myVar will refer to the local (parameter or variable) myVar. In order to access the class member also called myVar, you need to explicitly use "this->".

Joe Schneider
+21  A: 

Usually, you do not have to, this-> is implied.

Sometimes, there is a name ambiguity, where it can be used to disambiguate class members and local variables. However, here is a completely different case where this-> is explicitly required.

Consider the following code:

template<class T>
struct A {
   int i;
};

template<class T>
struct B : A<T> {

    int foo() {
        return this->i;
    }

};

int main() {
    B<int> b;
    b.foo();
}

If you omit this->, the compiler does not know how to treat i, since it may or may not exist in all instantiations of A. In order to tell it that i is indeed a member of A<T>, for any T, the this-> prefix is required.

Note: it is possible to still omit this-> prefix by using:

template<class T>
struct B : A<T> {

    using A<T>::i; // explicitly refer to a variable in the base class

    int foo() {
        return i; // i is now known to exist
    }

};
ASk
I'm glad someone pointed this one out.
Michael Burr
Nice use of using declaration :)
Faisal Vali
This is a particularly nasty case. I've been bitten by it before.
Jason Baker
+2  A: 
  1. Where a member variable would be hidden by a local variable
  2. If you just want to make it explictly clear that you are calling an instance method/variable


Some coding standards use approach (2) as they claim it makes the code easier to read.

Example:
Assume MyClass has a member variable called 'count'

void MyClass::DoSomeStuff(void)
{
   int count = 0;

   .....
   count++;
   this->count = count;
}
zebrabox
+4  A: 

There are several reasons why you might need to use this pointer explicitly.

  • When you want to pass a reference to your object to some function.
  • When there is a locally declared object with the same name as the member object.
  • When you're trying to access members of dependent base classes.
  • Some people prefer the notation to visually disambiguate member accesses in their code.
avakar
A: 

The other uses for this (as I thought when I read the summary and half the question... .), disregarding (bad) naming disambiguation in other answers, are if you want to cast the current object, bind it in a function object or use it with a pointer-to-member.

// casting

void Foo::bar() {
    misc_nonconst_stuff();
    const Foo* const_this = this;
    this->bar(); // calls const version
} 

void Foo::bar() const {}

// binding

void Foo::baz() {
     for_each(m_stuff.begin(), m_stuff.end(),  bind(&Foo:framboozle, this, _1));        
} 

void Foo::framboozle(StuffUnit& su) {}

std::vector<StuffUnit> m_stuff;

// ptr-to-member

void Foo::boz() {
    bez(&Foo::bar);
    bez(&Foo::baz);
} 

void Foo::bez(void (Foo::*func_ptr)()) {
    for (int i=0; i<3; ++i) {
        (this->*func_ptr)();
    }
}

Hope it helps to show other uses of this than just this->member.

Marcus Lindblom
+1  A: 

One other case is when invoking operators. E.g. instead of

bool Type::operator!=(const Type& rhs)
{
    return !operator==(rhs);
}

you can say

bool Type::operator!=(const Type& rhs)
{
    return !(*this == rhs);
}

Which might be more readable. Another example is the copy-and-swap:

Type& Type::operator=(const Type& rhs)
{
    Type temp(rhs);
    temp.swap(*this);
}

I don't know why it's not written swap(temp) but this seems to be common.

rlbond
A: 

I found another interesting case of explicit usage of the "this" pointer in the Effective C++ book.

For example, say you have a const function like

  unsigned String::length() const

You don't want to calculate String's length for each call, hence you want to cache it doing something like

  unsigned String::length() const
  {
    if(!lengthInitialized)
    {
      length = strlen(data);
      lengthInitialized = 1;
    }
  }

But this won't compile - you are changing the object in a const function.

The trick to solve this requires casting this to a non-const this:

  String* const nonConstThis = (String* const) this;

Then, you'll be able to do in above

  nonConstThis->lengthInitialized = 1;
Ariel
+1  A: 

Although I usually don't particular like it, I've seen others use this-> simply to get help from intellisense!

cantabilesoftware
A: 

Use the this pointer in operator= :

class Foo
{
  :  :
  Foo& operator=(const Foo& rhs)
  {
    :  :
    return * this;
  }
};
John Dibling