4

What is the proper use of the this self-reference of a class?

I sometimes use it inside a method to clear out that the variable used is a member variable and not one declared inside the method, but on the other side I am wondering if this is a good reason to do so, as I think you should always code (and comment) in a way which is self-explaining and therefore would make such an unneeded use of this unnecessary and another reason against it would be that you are actually producing more code than needed.

void function() {
  while(i != this->length) //length is member var
     /*do something*/
}

Another way of using it I frequently encounter is inside constructors (mostly in Java), as the parameters do have the same name as the member variables which has to be initialized. As the Primer states that this is bad code I am not doing this, but on the other side, I see how using the same name as the member-vars as parameter names clears out of which use they are.

C++
Constructor::Constructor(int size,int value) : this->size(size),
                                               this->value(value) {};

Java
Constructor(int size,int value) {
  this->size = size;
  this->value = value;
}

I hope there is actually a rule considering both languages (Java/c++), if not I will retag for just c++ as this is the one I am more interested in.

Tamás Szelei
  • 23,169
  • 18
  • 105
  • 180
Sim
  • 4,199
  • 4
  • 39
  • 77

6 Answers6

10

For the most part, this-> is redundant. The exception is if you have a parameter or a local variable of the same name (easily, and probably best avoided), or in a template, in order to force the following symbol to be dependent—in this latter use, it is often unavoidable.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Could you post a micro example of the template situation? I think that's very illuminating. – Kerrek SB Nov 28 '11 at 17:30
  • @KerrekSB: [There](http://stackoverflow.com/questions/8299874/use-of-in-a-template-in-order-to-force-the-following-symbol-to-be-dependent) you go! – Alok Save Nov 28 '11 at 17:39
  • @KerrekSB `template struct base { virtual void f() {}; }; template struct derived : base { void g() { this->f(); } };` is such an example, without the `this->` the `x` identifier is non-dependent and should not resolve to `base::x` (VS incorrectly allows this). You can manually force the resolution by qualifying with `base::f()`, but that will also disable dynamic dispatch, so the only way of calling `f` polymorphically inside `derived` is with the `this` keyword. – David Rodríguez - dribeas Nov 28 '11 at 17:39
2

this isn't necessary here as only members can be in init lists:

Constructor::Constructor(int size,int value) : size(size), // no need for this->
                                           value(value) {};

The only other use of this-> is in templates.

template <class T>
struct foo : T {
  void bar() {
    this->x = 5; // T has a member named x
  }
};

If you don't have to use it then don't. Avoid having function parameters with the same name as members for things other than constructors and set methods.

Pubby
  • 51,882
  • 13
  • 139
  • 180
1

using this-> explicitly states that you're referring to a member method/variable. Commenting to say this is just redundant... unless for some reason you have a local variable AND a member variable that have the same name and are manipulating them differently in the same code block, e.g.:

int x = 7;
this->x = 8; // yes, I really mean the member variable here
Marc B
  • 356,200
  • 43
  • 426
  • 500
  • but wouldn't using the same name twice be already considered bad coding? – Sim Nov 28 '11 at 17:24
  • bad practice, but not bad coding. The compiler knows which variable you're talking about, because `x` and `this->x` are two completely different variables. – Marc B Nov 28 '11 at 17:25
  • @Sim usually yes doing this is a sign of a bad name. However there are patterns eg Java constructors where this is considered normal. – andy boot Nov 28 '11 at 17:26
1

Using this-> increases the length of your program, so it adds to the cognitive overhead of reading it. The only sensible use of it is when there is something in scope that shadows a member of the class and you want to access the member instead. Shadowing identifiers is a bad idea in most cases and there is a compiler switch in gcc (-Wshadow) that helps to avoid it.

Tamás Szelei
  • 23,169
  • 18
  • 105
  • 180
  • *Using this-> increases the length of your program, so it adds to the cognitive overhead of reading it.* What? Can you explain that part? – Praetorian Nov 28 '11 at 17:34
  • 1
    Yes (maybe I didn't use the right word? English is not my first language). What I meant is that when someone (or even yourself) reads your program they will have to read and understand more code if you put this-> everywhere. Especially for a keyword that is highlighted, it occupies the thought process of understanding the code more compared to if it wasn't there. It's not significant for one instance, but it adds up. In other words, more code potentially leads to an increased [WTFs/min](http://www.osnews.com/story/19266/WTFs_m). – Tamás Szelei Nov 28 '11 at 18:16
  • +1 for the wtfs/min, never heard of it but loved it as soon as i saw – Sim Nov 29 '11 at 13:12
1

The use of this in the constructor is not necessary: compilers are smart enough to tell parameter names from member names. The snippet below compiles and runs just fine:

Constructor::Constructor(int size,int value) : size(size), value(value) {};

In general, use of this for disambiguation is valid, but unnecessary: as you correctly noted, you can simply use different names for parameters and members, and that's that. However, there are cases when you must use this, otherwise things are not going to compile. Here is a somewhat contrived example - using this to set up a "back reference", as follows:

class Callback {
    Client *client;
public:
    Callback(Client* client) : client(client) {}
    // ...
}

class Client {
    Callback callback;
public:
    Client() : callback(this) {} // You must use 'this' here
    // ...
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

Personally I prefer to name my variables in a way so that I see they are instance variables e.g. m_foo. I use only this-> if the compiler requires me to due to some ambiguity because i find the code gets a bit difficult to read with expression that have lots of this-> in them

AndersK
  • 35,813
  • 6
  • 60
  • 86