When should I explicitly use the `this` pointer?

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

+57
c ++ this
Jun 14 '09 at 18:02
source share
13 answers

Usually you do not need this-> implied.

Sometimes a name is ambiguous, where it can be used to eliminate the ambiguity of class members and local variables. However, here is a completely different case when this-> 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 instances of A To say that i indeed a member of A<T> , any T requires the this-> prefix.

Note. You can omit this-> prefix with:

 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 } }; 
+72
Jun 14 '09 at 18:12
source share
β€” -

If you declare a local variable in the method with the same name as the 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; af(); } 

prints:

5
four

+19
Jun 14 '09 at 18:10
source share

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

  • If you want to pass a link to your object to some function.
  • When there is a locally declared object with the same name as the member object.
  • When you try to access elements of dependent base classes .
  • Some people prefer to denote visually disambiguating member access in their code.
+13
Jun 14 '09 at 18:18
source share
  • If a member variable will hide the local variable
  • If you just want it to be clearly clear that you are calling an instance method / variable


Some coding standards use approach (2) because they claim to make it easier to read code.

Example:
Suppose MyClass has a member variable called "count"

 void MyClass::DoSomeStuff(void) { int count = 0; ..... count++; this->count = count; } 
+3
Jun 14 '09 at 18:13
source share

Another case is calling operators. For example. instead

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

you can say

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

What could be more readable. Another example is copy and swap:

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

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

+3
Jun 14 '09 at 18:24
source share

Although I usually don’t particularly like it, I have seen others use it-> just to get help from intellisense!

+3
Jun 14 '09 at 23:29
source share

There are several cases of using this , and there are others where using the this pointer is one way to solve the problem.

1) Alternatives are available . To eliminate the ambiguity between local variables and class members, as @ASk shows .

2) There is no alternative: To return a pointer or a link to this from a member function. This is often done (and should be done) by overloading operator+ , operator- , operator= , etc.:

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

Doing this resolves the idiom known as the " chain of methods ", where you perform several operations on an object in a single line of code. For example:

 Student st; st.SetAge (21).SetGender (male).SetClass ("C++ 101"); 

Some consider this consise, others consider it an abomination. Count me in the last group.

3) There is no alternative:. To resolve names in dependent types. This happens when using templates, as in this example:

 #include <iostream> template <typename Val> class ValHolder { private: Val mVal; public: ValHolder (const Val& val) : mVal (val) { } Val& GetVal() { return mVal; } }; template <typename Val> class ValProcessor : public ValHolder <Val> { public: ValProcessor (const Val& val) : ValHolder <Val> (val) { } Val ComputeValue() { // int ret = 2 * GetVal(); // ERROR: No member 'GetVal' int ret = 4 * this->GetVal(); // OK -- this tells compiler to examine dependant type (ValHolder) return ret; } }; int main() { ValProcessor <int> proc (42); const int val = proc.ComputeValue(); std::cout << val << "\n"; } 

4) Available alternatives . As part of the coding style, member variables are used to document variables, not local variables. I prefer a different naming scheme in which varibales members can never have the same name as local ones. I am currently using mName for members and name for local users.

+3
Jun 15 '09 at 4:32
source share

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

 class Foo { protected: int myX; public: Foo(int myX) { this->myX = myX; } }; 
+2
Jun 14 '09 at 18:11
source share

You need to use this -> if you have a character 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 interesting points in the code, referring to myVar, it will refer to the local (parameter or variable) myVar. To access a member of the class, also called myVar, you need to explicitly use "this β†’".

+2
Jun 14 '09 at 18:11
source share

Another uses for this (as I thought when I read the summary and half of the question ...), ignoring the (bad) naming of ambiguity in other answers - this is if you want to use the current object, bind it to a function object or use it with a pointer per element.

Casts

 void Foo::bar() { misc_nonconst_stuff(); const Foo* const_this = this; const_this->bar(); // calls const version dynamic_cast<Bar*>(this)->bar(); // calls specific virtual function in case of multi-inheritance } void Foo::bar() const {} 

Snap

 void Foo::baz() { for_each(m_stuff.begin(), m_stuff.end(), bind(&Foo:framboozle, this, _1)); for_each(m_stuff.begin(), m_stuff.end(), [this](StuffUnit& s) { framboozle(s); }); } 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 this helps show another use of this, and not just this β†’ member.

+2
Jun 14 '09 at 18:22
source share

Some people talked about how this should be a reference, and I could not agree more. I just wanted to say that the ugly precompiler line can mimic this:

 #define self (*this) 

Do not use this :-)

+2
May 10 '16 at 9:01 pm
source share

I found another interesting case of explicitly using the "this" pointer in an Effective C ++ book.

For example, let's say you have a const function, for example

  unsigned String::length() const 

You do not want to calculate the length of the string for each call, so you want to cache it by doing something like

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

But this will not compile - you change the object in the const function.

The trick to solve this requires attributing it to non-constant:

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

Then you can do it higher

  nonConstThis->lengthInitialized = 1; 
0
Jun 14 '09 at 18:27
source share

The main (or I can say the only) purpose of the this pointer is that it points to the object used to call the member function.

The basics for this purpose, we may have some cases that can only be solved with the help of this pointer.

For example, we must return the calling object in a member function with an argument - this is the same class object:

 class human { ... human & human::compare(human & h){ if (condition) return h; // argument object else return *this; // invoking object } }; 
0
02 Sep '15 at 15:09
source share



All Articles